我需要从绑定成员函数创建一个谓词,所以我将它包装在boost::function<bool(SomeObject const &)>
中。这看起来很好,但是我还需要在一个案例中否定它。然而
boost::function<bool(SomeObject const &)> pred;
std::not1(pred);
不能在MSVC ++ 9.0(Visual Studio 2008)下编译,抱怨对引用的引用无效:
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(213) : warning C4181: qualifier applied to reference type; ignored
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\functional(213) : error C2529: '_Left' : reference to reference is illegal
问题是boost::function
将argument_type
定义为SomeObject const &
,std::unary_negate<_Fn1>
实例化的std::not1
在内部尝试使用const typename _Fn1::argument_type&
和编译器拒绝它,因为T::argument_type
已经是一个参考。我确信这应该在C ++ 11下编译,但这只是旧的编译器,只是C ++ 03。所以我想知道它是谁的错:
unary_negate
带有const typename Predicate::argument_type& x
参数),argument_type
也不应该被引用
boost::function
不应该与引用参数一起使用?答案 0 :(得分:1)
错误肯定不是Boost的; boost::function
基本上只是std::function
,具有相同的语义。带参考参数的boost::function
也可以正常工作。您不能将它们与std::not1
或其他<functional>
内容一起使用。
C ++ 11的引用 - 折叠使std::not1
按照您认为应该的方式工作。如果没有引用 - 折叠,在C ++ 03中指定std::not1
的方式是不可能的 - 除了在实现中执行者做了一些创造性解释而不是盲目遵循标准字母的实现。
可能使std::not1
在C ++ 03中工作,为参考std::unary_negate
的谓词添加argument_type
的特化,但是libc ++也没有libstdc ++已经这样做了。
但你知道谁有? 提升!如果您只是将代码更改为使用boost::not1
当前使用的std::not1
,everything will work fine.基本上,请将boost
命名空间视为它是std
的C ++ 11兼容版本;在C ++ 11的std
命名空间中工作的任何东西都可以在C ++ 03的boost
命名空间中运行。
警告,希望偏离主题:我的Macbook上的Clang编译器(Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
)甚至在-std=c++03
模式下静默地折叠引用,以便
typedef const int& ref;
typedef const ref& ref2;
不会产生错误。当您测试C ++ 03代码时,请确保您没有使用具有此错误的编译器。