`decltype` как часть спецификации типа шаблона в объявлении функции шаблона - PullRequest
1 голос
/ 13 января 2012

следующий код компилируется в 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 ); 
}

Комментарий указывает на проблемную строку и показывает исправление (которое не являетсядействительно исправление с точки зрения дизайна, просто исправление компиляции).Несколько вопросов:

  1. Правильно ли MSVC ++ скомпилировать это?

  2. Если бы нам пришлось изменить порядок параметров в

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 в объявлении функции позже?Или я здесь упускаю что-то фундаментальное (возможно, какой-то параграф из Стандарта)?

1 Ответ

1 голос
/ 13 января 2012
  1. Я считаю, что MSVC является правильным.

  2. Нельзя ссылаться на более поздний параметр в объявлении более раннего, поскольку имя еще не находится в области видимости.,Чтобы определить тип вашего параметра fA, оба параметра fP и fF должны находиться в области видимости, чтобы можно было оценить выражение decltype.

ЕслиВы явно указываете параметры шаблона, после чего он работает с gcc:

Func< true,decltype(&Foo<double>),double>( Foo< double >, -1.2, 2.1 );

Это и тот факт, что указание "double" непосредственно в качестве параметра для TA подразумевает, что использование зависимого типа для *Параметр 1019 * предотвращает вычет типа для PF и PP.Я не понимаю, почему это так.

...