`decltype` как часть спецификации типа шаблона в рамках объявления функции шаблона

StackOverflow https://stackoverflow.com/questions/8847361

Вопрос

А Следующий код компилируется в 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. Я считаю, что MSVC прав.

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

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

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

Что и тот факт, что определение «двойного» непосредственно в качестве параметра для TA Работы подразумевают, что использование зависимого типа для TA Параметр предотвращает вычет типа для PF а также PP. Анкет Я не понимаю, почему это будет хотя.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top