gpt4 book ai didi

c++ - `decltype` 作为模板函数声明中模板类型规范的一部分

转载 作者:太空宇宙 更新时间:2023-11-04 12:13:22 25 4
gpt4 key购买 nike

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 && 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 )

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

最佳答案

  1. 我相信 MSVC 是正确的。

  2. 您不能在较早参数的声明中引用较晚参数,因为该名称尚未在范围内。为了确定您的 fA 参数的类型,fPfF 都必须在范围内,以便 decltype 表达式可以求值。

如果您明确指定模板参数,那么它可以与 gcc 一起使用:

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

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

关于c++ - `decltype` 作为模板函数声明中模板类型规范的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8847361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com