在模板功能和自动类型扣除之间进行选择

Dav*_*rcz 3 c++ templates auto c++14 c++17

我有一个关于模板函数与函数自动类型推导的一般性问题.

多年来,我们已经能够编写模板功能:

template <class T> T add(T a,T b){
    return a+b;
}
Run Code Online (Sandbox Code Playgroud)

有一个TS用于使用auto来进行函数的参数推导

auto add(auto a,auto b){
    return a+b;
}
Run Code Online (Sandbox Code Playgroud)

我虽然使用auto,但是没有办法获得实际类型,例如使用静态成员,但这样做很好:

#include <iostream>

struct foo
{
    static void bar(){std::cout<<"bar"<<std::endl;}
    static int i ;
};
int foo::i{0};
void t(auto f){
    decltype(f)::bar();
    std::cout<<    decltype(f)::i<<std::endl;
}
int main(int argc, char *argv[])
{
    t(foo());
    return 0;
}    
Run Code Online (Sandbox Code Playgroud)

那么有没有理由选择一个而不是另一个?

Jer*_*fin 5

这个特定代码的明显原因是它们根本没有完全相同的语义.

特别是,如果您传递不同类型的参数,则使用的版本auto将为每个参数独立推导出一种类型,然后根据这些推断出结果的类型.

相反,对于模板版本,您只指定了一种类型,因此参数必须都是相同的类型(结果将是相同的).

所以,为了让代码更接近等价,你真的需要更像这样编写模板:

template <class T, class U> 
auto add(T a, U b) -> decltype(a+b) {
    return a+b;
}
Run Code Online (Sandbox Code Playgroud)

这显然也是可能的,但为支持使用的论据增加了更多的力量auto.

  • 有几种方法可以使您的代码不等同于自动版本(衰变,sfinae). (3认同)
  • @Columbo如果`a + b`返回一个引用,` - > decltype`版本的`add`返回一个引用,而`auto`版本返回一个值类型(并且衰减).这可以通过`decltype(auto)add(auto a,auto b){return a + b;}`版本修复(但我还没有完全掌握自动模板函数的C++ 1z提议) ). (3认同)