C ++ 03下的参考折叠

时间:2012-10-05 11:05:49

标签: visual-c++-2008 c++03

我需要从绑定成员函数创建一个谓词,所以我将它包装在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::functionargument_type定义为SomeObject const &std::unary_negate<_Fn1>实例化的std::not1在内部尝试使用const typename _Fn1::argument_type&和编译器拒绝它,因为T::argument_type已经是一个参考。我确信这应该在C ++ 11下编译,但这只是旧的编译器,只是C ++ 03。所以我想知道它是谁的错:

  • 编译器,因为它应该折叠引用(apparently not)
  • 标准库,因为它应该准备好处理引用的函子(显然不是,因为规范定义unary_negate带有const typename Predicate::argument_type& x参数),
  • 提升,因为即使实际参数是
  • argument_type也不应该被引用
  • 我的,因为boost::function不应该与引用参数一起使用?

1 个答案:

答案 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::not1everything 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代码时,请确保您没有使用具有此错误的编译器。