模板化类构造函数在结构中使用错误的重载
Templated class constructor uses wrong overload when in struct
测试如下:
class NotInit{};
NotInit NOT_INIT;
template<class T>
class Optional{
T value;
bool has_value;
public:
Optional() : value(), has_value(false){}
explicit Optional(NotInit):value(), has_value(false) {}
explicit Optional(T const & val):value(val), has_value(true){}
explicit Optional(Optional<T> const & other) {}
Optional& operator=(Optional<T> const & other){}
Optional& operator=(T const & other){}
};
enum X {
FIRST
};
struct Some {
Optional<X> member;
};
int main(int, char**){
Optional<X> const opt(NOT_INIT);
Some s = {NOT_INIT};
return 0;
}
Clang 3.4 抱怨:
../st.cpp:31:12: error: no viable conversion from 'NotInit' to 'Optional<X>'
Some s = {NOT_INIT};
^~~~~~~~
1 error generated.
为什么它抱怨结构初始化,而抱怨可变量?为什么它没有选择具有正确参数的构造函数?
缺少什么重载,以便我可以使用它来初始化结构?
我无法使用 boost,我不确定如果使用 boost::optional
不会出现此错误。
您正在将构造函数标记为explicit
。因此,当您尝试使用大括号初始值设定项列表初始化struct Some
时,您将触发隐式转换...
此处可防止这种情况:
class NotInit;
template <typename T>
class Optional {
// Here => Optional(NotInit) cannot be called implicitly
explicit Optional(NotInit):value(), has_value(false) {}
};
/* ... */
Some s = {NOT_INIT}; // Implicit call to Optional<X>(NotInit): whoops!
如果删除explicit
,则可以保留:
Some s = {NOT_INIT};
如果您选择不这样做,则必须像这样实例化s
:
Some s = {Optional<X>(NOT_INIT)};
在任何情况下,您都必须删除复制构造函数上的 explicit
关键字(它必须执行复制而不是"虚拟"构造函数)。
为什么?因为一旦Optional<X>
对象从NOT_INIT
构建,就必须复制s.member
。
注意:您还可以提供一个移动构造函数,在这种情况下会更合适,因为您从NOT_INIT
转换中获得的对象是右值。
相关文章:
- 错误 没有与参数列表匹配的重载函数"getline"实例
- 在运算符重载定义中使用成员函数(const错误)
- 重载方法的方式会在使用临时调用时生成编译器错误
- 数组索引重载错误
- C++:需要帮助了解运算符重载错误
- 在类Bat代码中,这给了我错误:重载的"Bat()"的调用是不明确的Bat(;)
- 不明确的错误重载运算符<<QdataStream 子类和个人类
- 具有相同参数的不同模板模板参数的错误重载函数
- 编译错误:重载函数的多个实例与 arument 列表匹配
- clang-libc++错误:重载解析选择了隐式删除的复制赋值运算符
- 错误:重载的调用不明确
- C++ 编译器选择输出流运算符<<的错误重载
- 分段错误重载运算符<<
- 错误:重载函数的多个实例与参数列表匹配
- 错误:重载的“max(int, int)”的调用不明确
- C++编译器选择类成员函数的错误重载
- 编译错误:重载操作符()
- 错误:重载的“bind(int(Class::*)(int,int),Class*,int,int”的调用不明确
- 未解析的外部符号错误重载操作符+模板
- 错误重载在构建"OpenSubdiv"时具有类似的转换