模板化的构造函数无法执行转换

时间:2019-06-18 07:50:19

标签: c++ templates c++14

这是我要实现的目标的独立用例

//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文字的错误。

1 个答案:

答案 0 :(得分:2)

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

  

Foo.hpp:实例化为“ Foo :: Foo(const T_0&)[with T_0 = int]”:

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

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

  

Foo.hpp:12:36:错误:“ formatter_name”不是“ int”的成员。

这是正确的:原始类型int根本没有成员,因此尤其没有formatter_name成员。

这说明了C ++标准所规定的错误。


现在,您提到期望转换了,是因为 non -explicit的构造函数是Hole接受了double吗?

如果是这样,则仅当您为期望Hole实例的“上下文”提供了双精度时,这种转换才会隐式发生。

例如,如果您将Foo初始化更改为Foo f<Hole>(43.0);Foo f(Hole{43.0});

在您的示例中,绝对不是这种情况:您为Foo构造函数提供了一个以参数类型为模板的double,并且您自己没有强制模板类型。因此,函数模板类型推导起作用了,它与参数类型完全匹配。此外,实施任何转换运算符都不会改变这一事实。