C++ 模板化构造函数无法执行转换
这里是一个我试图实现的独立用例C++ 模板化构造函数无法执行转换,c++,templates,c++14,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 然后我有一个类,它使用这
//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
literal的错误。让我们分析编译器错误:
Foo.hpp:在“Foo::Foo(const T_0&)[with T_0=int]”的实例化中:
表示T\u 0
被推断为类型int
(旁注:您确定在尝试使用43
文字而不是43.0
时没有给出错误吗?)
因此,T_0
的类型从此处固定。然后:
Foo.hpp:12:36:错误:“格式化程序名称”不是“int”的成员
这是正确的:原语类型int
根本没有成员,因此它没有formatter\u name
成员
<>这解释了错误,这是由C++标准规定的。< /P>
现在,您提到期望转换,是因为
孔的非显式构造函数采用了双
如果是这样的话,只有当您为一个“上下文”提供了一个double,该“上下文”需要一个洞
实例时,这种转换才会隐式发生
例如,如果将Foo
初始化更改为Foo f(43.0)代码>或foof(孔{43.0})代码>
在您的示例中,情况绝对不是这样:您为参数类型上模板化的Foo
构造函数提供了一个double-to,并且您自己不强制使用模板类型。因此,函数模板类型推断开始生效,并且它与参数类型完全匹配。此外,实现任何转换运算符都不会改变这一事实。您的代码根本不使用孔。您是否希望这样做int→双重的→洞→Foo
?如果我有Foo f(43.0)
?如果Foo
直接接受任何类型,那么编译器有什么理由认为首先转换到Hole
更好呢?如果我定义一个名为Hloe
的类,除了名称之外,它相当于Hole
,您希望编译器做什么?编译器做隐式转换。但编译器不是通灵的。它猜不出你的意思是Foo(Hole)
而不是你写的template Foo(const t&)
。