`decltype` как часть спецификации типа шаблона в рамках объявления функции шаблона
-
27-10-2019 - |
Вопрос
А Следующий код компилируется в 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
объявлено в объявлении функции позже? Или я упускаю здесь что -то фундаментальное (возможно, какой -нибудь абзац из стандарта)?
Решение
Я считаю, что MSVC прав.
Вы не можете ссылаться на более поздний параметр в объявлении более раннего, потому что имя еще не в области. Чтобы определить тип вашего
fA
параметр, обаfP
а такжеfF
Должен быть в сфере, чтобыdecltype
Выражение может быть оценено.
Если вы явно указали параметры шаблона, то он работает с GCC:
Func< true,decltype(&Foo<double>),double>( Foo< double >, -1.2, 2.1 );
Что и тот факт, что определение «двойного» непосредственно в качестве параметра для TA
Работы подразумевают, что использование зависимого типа для TA
Параметр предотвращает вычет типа для PF
а также PP
. Анкет Я не понимаю, почему это будет хотя.