现在使用boost::variant<bool, int, std::string>来存储token的内容。
boost::variant会自动根据里面的类型匹配正确的<<,std::cout<<token<<std::endl;是可行的
然而在输出时,我们希望改变输出时的表现。
改变输出时的表现有两种方法:
改变流本身,自定义新流的<<操作符。考虑到这样对整体侵入过大,遂放弃。
给它们创建一个Formatter:(这是stackoverflow上的一个答案)
template <class T>
class MyFormatting;
template <>
class MyFormatting<int>
{
private:
const int& nucleus;
public:
MyFormatting(const int& n) : nucleus(n) {}
friend std::ostream& operator << (std::ostream& os, const MyFormatting& w)
{
return os << "int:" << w.nucleus;
}
};
//... specilization for bool and std::string
template <class... T>
using Variant_Formatting_t = boost::variant < MyFormatting<T>... > ;
Variant_Formatting_t<bool, int, std::string>
FMT(const boost::variant<bool, int, std::string>& A__)
{
return Variant_Formatting_t<bool, int, std::string>{A__};
}
int main()
{
boost::variant<bool, int, std::string> var_int = 3;
boost::variant<bool, int, std::string> var_str = "12312312";
std::cout << FMT(var_int)<< FMT(var_str) << std::endl;
}
这种方法在只有int & string时是有效的,因为:
Variant_Formatting_t<bool, int, std::string>{3};
中,
Variant_Formatting_t作为variant< MyFormatter<bool>, MyFormatter<int>, ... >
会尝试调用initilize(void, 3)
而其原型有
initilize(void, const MyFormatter<string>&)
与
initilize(void*, const MyFormatter<int>&)
只有(2)可以匹配,完成转换
然而,当我们加上bool时,由于
initilize(void, 3)
有了3个原型:
initilize(void, const MyFormatter<string>&)
initilize(void, const MyFormatter<int>&)
initilize(void, const MyFormatter<bool>&)
其中2 3的优先级是等价的(都是template class conversion),从而导致这段代码失败
请问有什么好的解决办法吗?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.