我试图创建一个类,它可以隐式转换为各种不同的类型,包括原语和自定义类。我希望能够转换为的类型之一是std::string。下面是一个可以转换为各种不同类型的示例类。它抛出错误“error:ambiguous overload for 'operator='"。这是因为std::string有一个来自ChartT的赋值运算符,编译器可以从int创建它。我的问题是,有没有可能有一个类既可以隐式转换为整数类型,也可以隐式转换为字符串类型?
class Test {
public:
operator double() const {
return 3.141592;
}
operator std::int64_t() const {
return -999;
}
operator std::uint64_t() const {
return 999;
}
operator bool() const {
return true;
}
operator std::string() const {
return "abcd";
}
};
int main(int argc, char** argv) {
std::string test_str = Test();
test_str = Test();
std::cout << test_str;
}
字符串
有趣的是,当我在定义test_str的同一行上赋值给它时,编译器不会抛出错误,因为它使用的是简单的构造函数而不是赋值运算符,但是它在下面的一行上出错了。
任何帮助将不胜感激。
1条答案
按热度按时间7rfyedvj1#
std::string
有几个重载的operator=
,参数如下:std::string
,const char *
,char
,std::initializer_list
。为了使代码正常工作,编译器需要选择一个,但至少有两个可能是合适的:
std::string
和char
,使用标量operator
的隐式转换。尽管后者会在以后引起歧义,但编译器似乎没有达到这一点。解决方案是进行一个模板化的转换
operator
,并使用SFINAE将其限制为特定类型:然后以下工程:
字符串
static_assert
并不是必需的,因为我们已经有了requires
,它只是在你向requires
添加更多类型而忘记了一个分支时提供一个更好的错误。注意
value<false, T>
而不是false
。尝试将false
直接放在那里会导致某些编译器无条件地发出错误,即使没有采用分支使用依赖于T
的表达式会使编译器将测试延迟到实际的示例化(因为就它所知,value
可以被专门化为某些T
的true
)。当我在定义test_str的同一行上赋值时,
这是一个初始化,而不是赋值。它调用一个构造函数,而不是
operator=
。