`decltype`:函数返回类型`T`转换为`T&`用于用户定义的类型(VS2010)

时间:2012-01-06 14:00:05

标签: c++ templates return-type decltype

编辑:GCC编译得很好,这是VS2010问题。感谢您将我指向ideone.com!

尝试编译以下内容时(VS2010):

#include <iostream>

template< typename PF01, typename PF02 >
inline auto FCall01( PF01 fCallee, PF02 && fParameter00 ) -> decltype( fCallee( std::forward< PF02 > ( fParameter00 ) ) )
{
 decltype( fCallee( std::forward< PF02 > ( fParameter00 ) ) ) lResult( fCallee( std::forward< PF02 >( fParameter00 ) ) ); // offending line for Foo03

 return ( lResult );
}

int gI = 0;
int & gCI = gI;

struct TA
{
  int mData;
  TA( int fData = 0 ) : mData( fData ) { }
  TA( TA const & fA ) : mData( fA.mData ) { }
};

int Foo00( int & fA ){ return ( fA ); }
int & Foo01( int & ){ return ( gCI ); }
int const & Foo02( int & ){ return ( gCI ); }
TA Foo03( int & fA ){ return ( TA( fA ) ); }

int main( void )
{
  decltype( FCall01( Foo00, gI ) ) l0( FCall01( Foo00, gI ) );
  l0 = -1;
  std::cout << gI << " : " << l0 << std::endl;

  decltype( FCall01( Foo01, gI ) ) l1( FCall01( Foo01, gI ) );
  l1 = -2;
  std::cout << gI << " : " << l1 << std::endl;

  decltype( FCall01( Foo02, gI ) ) l2( FCall01( Foo02, gI ) );
  const_cast< int & > ( l2 ) = -3;
  std::cout << gI << " : " << l2 << std::endl;

  decltype( FCall01( Foo03, gI ) ) l3( FCall01( Foo03, gI ) );
  l3.mData = -4;
  std::cout << gI << " : " << l3.mData << std::endl;

  return ( 0 );
}

我收到编译器警告:

Warning C4239: nonstandard extension used : 'initializing' : conversion from 'TA' to
'TA &'; A non-const reference may only be bound to an lvalue; see reference to function
template instantiation 'TA &FCall01<TA(__cdecl *)(int &),int&>(PF01,PF02) with
[PF01=TA(__cdecl *)(int &),PF02=int &]' being compiled.

对于内置类型,一切都很好,但对于用户定义的类型,模板函数decltype(...)中的FCallTA&而不是TA提供了FCall中的FCall返回类型和局部变量。

我没有看到它背后的逻辑,我认为标准说decltype(f())应该给出f()的确切返回类型。它适用于内置类型。对于用户定义的类型是否存在一些隐藏的问题,或者只是VS2010在我身上玩弄技巧?

P.S。我无法访问海湾合作委员会,请有人,请检查GCC编译是否没有警告?

1 个答案:

答案 0 :(得分:1)

这是VS2010中的编译器错误。它不会发生在GCC(ideone.com)和Visual C ++ 11 Developer Preview中。

感谢PlasmaHH和Xeo链接到ideone.com,感谢Jesse获取有关Visual C ++ 11 Developer Preview中错误状态的信息。

编辑:只是一个后续行动:VS2010中的这个错误发生在用户定义的类型具有用户定义的构造函数时。如果它没有(使用编译器生成的默认值),则不会发生错误。