这是我要实现的独立用例

//Bar.hpp

#ifndef BAR_HPP
#define BAR_HPP

constexpr bool areNamesEqual(const char* name1,const char* name2)
{
    return ((*name1 == *name2) && (*name1 == '\0' ||  areNamesEqual(name1 + 1,name2 + 1)));
}
#endif

然后我有一个使用此比较实用程序的类,如下所示
// Foo.hpp

#ifndef FOO_HPP
#define FOO_HPP

#include "Bar.hpp"

class Foo
{
    public:
    template<typename T_0>
    Foo(const T_0 & var_0)
    {
        static_assert(areNamesEqual(T_0::formatter_name,"Hole"),"Incorrect hole type supplied!");
    }
};

#endif

最后我有另一个类,它实际上为比较提供了一个参数,如下所示
// Hole.hpp

#ifndef HOLE_HPP
#define HOLE_HPP

class Hole {
    public:

        Hole(double dx) : d(dx) {}

        static constexpr const char* formatter_name = "Hole";
    private:
        double d;
  };
#endif

在我的main.cpp中,当我如下调用时
//main.cpp
#include "Foo.hpp"
#include "Hole.hpp"

int main()
{
    Foo f(43);
    return 0;
}

带--std = c++ 14的g++(6.3)给我以下错误
In file included from main.cpp:1:0:
Foo.hpp: In instantiation of ‘Foo::Foo(const T_0&) [with T_0 = int]’:
main.cpp:6:13:   required from here
Foo.hpp:12:36: error: ‘formatter_name’ is not a member of ‘int’
         static_assert(areNamesEqual(T_0::formatter_name,"Hole"),"Incorrect hole type supplied!");

为什么编译器无法将double类型隐式转换为Hole类?
我不确定Hole类的转换运算符是否会对我有所帮助。

:更新:
更新了代码段以显示int文字错误。

最佳答案

让我们分析一下编译器错误:



意味着T_0被推导为int类型(旁注:在尝试使用43文字而不是43.0时,您确定没有给出错误吗?)

因此,T_0的类型从此处固定。然后:



正确:原始类型int根本没有成员,因此它特别没有formatter_name成员。

这解释了错误,这是C++标准所规定的。

现在,您提到期望转换,是因为explicit-Hole构造函数采用double吗?

如果是这样,则仅当您给期望Hole实例的“上下文”赋予 double 时,才会隐式发生此转换。

例如,如果您将Foo初始化更改为Foo f<Hole>(43.0);Foo f(Hole{43.0});
在您的示例中,绝对不是这种情况:您给Foo构造函数加了一个 double ,该构造函数以参数类型为模板,并且您自己不强制模板类型。因此,函数模板类型推导起作用了,它与参数类型完全匹配。此外,实现任何转换运算符都不会改变这一事实。

10-07 20:20