следующий код компилируется в 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 )
не будет компилироваться, поскольку компилятор обрабатывает fP
в TA< decltype( fF( std::forward<PP>( fP ) ) ), pB >
как необъявленную переменную.По логике вещей, действительно ли компилятору нужно знать fP
на этом этапе, разве он все равно не анализирует всю декларацию, поскольку это функция с завершающим типом возврата?Почему он не может "пропустить" второй параметр функции и посмотреть, объявлено ли fP
в объявлении функции позже?Или я здесь упускаю что-то фундаментальное (возможно, какой-то параграф из Стандарта)?