【发布时间】:2012-01-13 07:42:44
【问题描述】:
following code 在 MSVC++ 中编译,但在 GCC 4.5.1 中不编译:
#include <iostream>
template< typename PT, bool pB >
struct TA
{
PT m;
TA( PT fT ) :
m( fT )
{
std::cout << "TA<" << pB << ">::TA() : " << m << std::endl;
}
PT operator()( PT fT )
{
std::cout << "TA<" << pB << ">::() : " << m << " and " << fT << std::endl;
return ( m );
}
};
template< typename PT >
PT Foo( PT fT )
{
std::cout << "Foo() : " << fT << std::endl;
return ( fT );
}
// Does not compile in GCC 4.5.1, compiles in MSVC++2010.
// Substitute TA< decltype( fF( std::forward<PP>( fP ) ) ), pB > with
// TA< double, pB > to compile with GCC.
template< bool pB, typename PF, typename PP >
auto Func( PF fF, PP && fP, TA< decltype( fF( std::forward<PP>( fP ) ) ), pB > && fA )
-> decltype( fF( std::forward<PP>( fP ) ) )
{
decltype( fF( std::forward<PP>( fP ) ) ) lResult( fF( std::forward< PP >( fP ) ) );
fA( lResult );
return ( lResult );
}
int main( void )
{
Func< true >( Foo< double >, -1.2, 2.1 );
return ( 0 );
}
注释指向有问题的行并显示修复(从设计的角度来看,这并不是真正的修复,只是编译修复)。几个问题:
MSVC++ 编译这个正确吗?
如果我们要改变参数的顺序
auto Func( PF fF, PP && fP, TA< decltype( fF( std::forward<PP>( fP ) ) ), pB > && fA )
到
auto Func( PF fF, TA< decltype( fF( std::forward<PP>( fP ) ) ), pB > && fA, PP && fP )
它不会编译,因为编译器将TA< decltype( fF( std::forward<PP>( fP ) ) ), pB > 中的fP 视为未声明的变量。从逻辑上讲,编译器此时真的需要知道fP,它是否不解析整个声明,因为它是带有尾随返回类型的函数?为什么它不能“跳过”第二个函数参数,然后查看 fP 是否在稍后的函数声明中声明?或者我在这里遗漏了一些基本的东西(也许是标准中的某些段落)?
【问题讨论】:
标签: c++ templates visual-c++ gcc decltype