2011-03-12 67 views
0

当包含boost :: exception时,我有两级变量struct的奇怪问题。我有下面的代码片段:组合boost :: exception和boost :: variant的问题

#include <boost/variant.hpp> 
#include <boost/exception/all.hpp> 

typedef boost::variant<int> StoredValue; 
typedef boost::variant<StoredValue> ExpressionItem; 
inline std::ostream& operator << (std::ostream & os, const StoredValue& stvalue) { return os;} 
inline std::ostream& operator << (std::ostream & os, const ExpressionItem& stvalue) { return os; } 

当我尝试编译它,我有以下错误:

boost/exception/detail/is_output_streamable.hpp(45): error C2593: 'operator <<' is ambiguous 
test.cpp(11): could be 'std::ostream &operator <<(std::ostream &,const ExpressionItem &)' [found using argument-dependent lookup] 
test.cpp(8): or  'std::ostream &operator <<(std::ostream &,const StoredValue &)' [found using argument-dependent lookup] 
1> while trying to match the argument list '(std::basic_ostream<_Elem,_Traits>, const boost::error_info<Tag,T>)' 
1> with 
1> [ 
1> _Elem=char, 
1> _Traits=std::char_traits<char> 
1> ] 
1> and 
1> [ 
1>  Tag=boost::tag_original_exception_type, 
1>  T=const type_info * 
1> ] 

代码片断简化尽可能在实际的代码是结构要复杂得多并且每个变体都有五个子类型。

当我删除的#include升压/异常/所有,并尝试下面的测试片段中,程序正确编译:

void TestVariant() 
{ 
    ExpressionItem test; 
    std::stringstream str; 
    str << test; 
} 

可能有人请告诉我如何使用时,以偶函数定义操作符< < boost :: Exception?

感谢和问候

里克

+0

我不认为这与boost :: exception有什么关系。这是输出流“operator <<”。但是我没有使用这个变体,因为你正在使用它 - 只有一种类型;我以为你应该至少有两种类型,因为这是一个“类固醇联合”,但也许有一些隐含的...我会重新访问文档。 – celavek 2011-03-13 00:02:00

+0

单一类型仅用于示例目的。在我的真实代码中,每个变体都有五个子类型。如果没有boost :: exception,包括一切正常。 – Rick 2011-03-13 00:06:15

+0

你的代码是否在boost命名空间中?我认为你的输出流操作符与为异常定义的操作符冲突。尝试把你的代码放在你自己的名字空间中。 – celavek 2011-03-13 00:13:50

回答

0

我不认为这有什么关系了boost ::例外。这是输出流“运营商< <”。但是我没有使用这个变体,因为你正在使用它 - 只有一种类型;我以为你应该至少有两种类型,因为这是一个“类固醇联合”,但也许有一些隐含的...我会重新访问文档。

您的代码是否在boost命名空间中?我认为你的输出流操作符与为异常定义的操作符冲突。尝试把你的代码放在你自己的名字空间中。

而对于运营商没有执行它可能仍然是选错了一个的问题......试图通过与命名空间和解析运算符前缀它作为你STD做用你的“< <”运营商:: stringstream的。

编辑:作为后续行动,以你最后的评论:你可以在自己的名称空间定义你的运营商,我们说了myNameSpace然后用你的版本明确需要的时候,例如

void TestVariant() 
{ 
    using namespace mynamespace; 

    ExpressionItem test; 
    std::stringstream str; 
    str << test; 
} 

它将与上述例子的工作,但我不知道这,是你所面临的确切情况......,我不是很熟悉精神

+0

使用名称空间来封装我的运算符<<并使用名称空间前缀来调用它绝对是一种解决方案。但是前缀不能用在我需要使用我的operator <<变体的现有库中。这就是为什么我需要在全局命名空间中定义operator <<的原因。谢谢。 – Rick 2011-03-13 08:40:42

+0

我不认为我完全理解。你是否希望你的操作员可以在现有的库中使用,并用它来代替标准的?就像在图书馆已经建成和运送? – celavek 2011-03-13 10:21:59

+0

例如助力精神库。我在语法中使用自己的结构/变体。为了调试目的(显示当前解析树),我需要显示我的结构的内容。这是通过在所有通过的结构上使用boperator <<内部精神机制完成的。所以我不能使用任何命名空间或任何其他黑客,但需要在全局命名空间中使用这些运算符<<。所有这些工作正常,直到boost :: exception不包括在内。所以问题可能在那里。 – Rick 2011-03-13 11:45:48