未推导出尾随类模板参数 [英] Trailing class template arguments not deduced

查看:160
本文介绍了未推导出尾随类模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码无法使用gcc 7.1.0进行编译,它会在main的第二行提供错误的模板参数。此版本的GCC是应该实施模板参数扣除类模板。



我认为编译器应该能够推出Bar的类模板参数T2,这意味着我不应该明确指定两个参数( Bar< int,int> )给出了 C ++ 17草案,其中说:可以推断(17.8.2)或从默认模板参数获得的尾随模板参数可以从显式模板参数列表。



我错了吗?编译器是否错误?这是一个疏忽或是故意的设计吗?

 模板< typename T> 
struct Foo {
Foo(T t){}
};

模板<类型名称T1,类型名称T2>
struct Bar {
Bar(T2 t){}
};

模板<类型名称T1,类型名称T2>
void bar(T2 t){}

int main(int argc,char ** argv){

Foo(42); //作品

Bar< int>(42); //不能编译
//模板参数的错误数目(1,应该是2)

bar< int>(42); // Works


解决方案

行为;不像模板参数推导(用于函数模板), class template argument deduction (自C ++ 17开始)只在没有提供模板参数时才起作用。 p>


仅在未提供模板
参数时才执行类模板参数推演。如果至少指定了一个参数,则不会发生
扣除。

  std :: tuple t(1, 2,3); // OK:演绎
std :: tuple< int,int,int> t(1,2,3); // OK:提供所有参数
std :: tuple< int> t(1,2,3); //错误:部分扣除


这意味着对于您的示例,您可以不利用类模板参数推导,而必须指定所有的模板参数。如果您希望类模板参数推演生效,您必须指定none,但无法推导出模板参数 T1


$ b $另一方面,下面的代码将起作用。

  template< typename T1,typename T2> 
struct Bar {
Bar(T1,T2){} //可以推导出T1
};

main main(int argc,char ** argv){
Bar bar(42,42); //利用类模板参数扣除
}


The code below fails to compile with gcc 7.1.0, which complains about providing the wrong number of template arguments in the second line of main. This version of GCC is supposed to implement template argument deduction of class templates.

I think the compiler should be able to deduce the class template argument T2 for Bar, which means that I shouldn't have to explicitly specify both arguments (Bar<int, int>) given paragraph 17.8.1.3 of the C++17 draft which says, "Trailing template arguments that can be deduced (17.8.2) or obtained from default template-arguments may be omitted from the list of explicit template-arguments."

Am I wrong? Is the compiler wrong? Is this an oversight or a deliberate design?

template <typename T>
struct Foo {
    Foo(T t) {}
};

template <typename T1, typename T2>
struct Bar {
    Bar(T2 t) {}
};

template <typename T1, typename T2>
void bar(T2 t) {}

int main(int argc, char **argv) {

    Foo(42); // Works

    Bar<int>(42); // Fails to compile with "wrong number of
                  // template arguments (1, should be 2)"

    bar<int>(42); // Works
}

解决方案

This is expected behavior; unlike template argument deduction (for function templates), class template argument deduction (since C++17) only works when no template arguments are provided.

Class template argument deduction is only performed if no template arguments are provided. If at least one argument is specified, deduction does not take place.

std::tuple t(1, 2, 3);              // OK: deduction
std::tuple<int,int,int> t(1, 2, 3); // OK: all arguments are provided
std::tuple<int> t(1, 2, 3);         // Error: partial deduction

That means for your example you can't take advantage of class template argument deduction and have to specify all the template arguments. If you want class template argument deduction taking effect you have to specify none, but the template parameter T1 can't be deduced.

On the other hand, the following code would work.

template <typename T1, typename T2>
struct Bar {
    Bar(T1, T2) {}   // make it possible to deduce T1
};

int main(int argc, char **argv) {
    Bar bar(42, 42); // take advantage of class template argument deduction
}

这篇关于未推导出尾随类模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆