【问题标题】:`decltype` as part of template type specification within declaration of a template function`decltype` 作为模板函数声明中模板类型规范的一部分
【发布时间】: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 ); 
}

注释指向有问题的行并显示修复(从设计的角度来看,这并不是真正的修复,只是编译修复)。几个问题:

  1. MSVC++ 编译这个正确吗?

  2. 如果我们要改变参数的顺序

auto Func( PF fF, PP &amp;&amp; fP, TA&lt; decltype( fF( std::forward&lt;PP&gt;( fP ) ) ), pB &gt; &amp;&amp; fA )

auto Func( PF fF, TA&lt; decltype( fF( std::forward&lt;PP&gt;( fP ) ) ), pB &gt; &amp;&amp; fA, PP &amp;&amp; fP )

它不会编译,因为编译器将TA&lt; decltype( fF( std::forward&lt;PP&gt;( fP ) ) ), pB &gt; 中的fP 视为未声明的变量。从逻辑上讲,编译器此时真的需要知道fP,它是否不解析整个声明,因为它是带有尾随返回类型的函数?为什么它不能“跳过”第二个函数参数,然后查看 fP 是否在稍后的函数声明中声明?或者我在这里遗漏了一些基本的东西(也许是标准中的某些段落)?

【问题讨论】:

    标签: c++ templates visual-c++ gcc decltype


    【解决方案1】:
    1. 我相信 MSVC 是正确的。

    2. 您不能在前一个参数的声明中引用后一个参数,因为该名称尚未在范围内。为了确定 fA 参数的类型,fPfF 必须在范围内,以便可以计算 decltype 表达式。

    如果您明确指定模板参数,则它适用于 gcc:

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

    直接将“double”指定为TA 的参数这一事实意味着对TA 参数使用依赖类型会阻止PFPP 的类型推导。我不明白为什么会这样。

    【讨论】:

    • 我猜那是 GCC 的问题。我习惯了 GCC 在语言结构方面更先进,所以我有点惊讶。顺便说一句,对于 GCC 来说,这是一个很好的“解决方法”,我没有检查过。
    猜你喜欢
    • 1970-01-01
    • 2013-09-18
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多