我有这样的结构:
// Literal.hpp
struct Literal
{
std::variant<
std::nullptr_t,
std::string,
double,
bool
>
value;
friend std::ostream &operator<<(std::ostream &os, Literal &literal);
};
而且我正在尝试像这样实现<
// Literal.cpp
Literal::Literal() : value(value) {}
std::ostream &operator<<(std::ostream &os, const Literal &literal)
{
std::visit(/* I don't know what to put here!*/, literal.value);
}
我已经尝试过像这样实现运算符(注意:我会采取任何优雅的解决方案,它不一定是下面的实现的解决方案)]
// In Literal.cpp
std::ostream &operator<<(std::ostream &out, const Literal literal)
{
std::visit(ToString(), literal.value);
return out;
}
struct ToString; // this declaration is in literal.hpp
void ToString::operator()(const std::nullptr_t &literalValue){std::cout << "null";}
void ToString::operator()(const char &literalValue){std::cout << std::string(literalValue);}
void ToString::operator()(const std::string &literalValue){std::cout << literalValue;}
void ToString::operator()(const double &literalValue){std::cout << literalValue;}
void ToString::operator()(const bool &literalValue){std::cout << literalValue;}
但是在我的主要函数中,传递char数组文字并不会在运行时将其转换为布尔值!忽略运算符重载,取一个字符:
main() {
Literal myLiteral;
myLiteral.value = "Hello World";
std::cout << myLiteral << std::endl;
}
const char*
不是value
可以容纳的类型。将"Hello World"
分配给myLiteral.value
时,有两个可能的转换链:
const char*
-> bool
const char*
-> std::string
前者是内置转换,而后者是用户定义的转换。因此,认为转换为bool
更好。
要解决此问题,您可以使用包装器功能,而不是直接设置value
:
struct Literal
{
std::variant<
std::nullptr_t,
std::string,
double,
bool
>
value;
template <typename T>
void setValue(T val)
{
value = val;
}
void setValue(const char* val)
{
setValue(std::string{val});
}
};
这利用了以下事实:重载解析将功能模板实例化视为比非模板函数更差的匹配,因此myLiteral.setValue("Hello World")
将调用Literal::setValue(const char*)
而不是Litaral::setValue<const char*>(const char*)
。