C++ boost::variant 重载<<的问题?

2015-07-31 11:59:02 +08:00
 htfy96

现在使用boost::variant<bool, int, std::string>来存储token的内容。

boost::variant会自动根据里面的类型匹配正确的<<,std::cout<<token<<std::endl;是可行的

然而在输出时,我们希望改变输出时的表现。

改变输出时的表现有两种方法:

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),从而导致这段代码失败

请问有什么好的解决办法吗?

1607 次点击
所在节点    问与答
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/209816

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX