类数据成员中可以使用模板参数推导吗?

Posted

技术标签:

【中文标题】类数据成员中可以使用模板参数推导吗?【英文标题】:Can template parameter deduction be used in class data members? 【发布时间】:2017-11-20 18:02:38 【问题描述】:

C++17 引入template argument deduction。

使用 gcc-7.2,我可以在函数中轻松使用它:

int test() 
  std::pair d(0, 0.0);

我希望在类非静态数据成员中使用相同的语法,例如:

class Test 
  std::pair d_0, 0.0;
;

但这会导致 gcc error: invalid use of template-name ... without an argument list--std=c++17 通过。

我尝试了一些其他的组合,但似乎都不起作用。

这是标准的预期行为,还是编译器不完全支持的情况?我在标准中找不到对类数据成员的任何明确引用。

我的用例当然要复杂得多,使用这种语法会非常方便(想想函数被传递和存储)。

【问题讨论】:

我不确定你到底在问什么。标准可以要求行为,委员会可以有意行为。您是指:1) 标准要求的行为,还是指 2) C++ 委员会预期的行为? @JohannesSchaub-litb 这个问题很清楚,询问它是按照标准还是编译器错误的正确行为。 可能的解决方法:decltype(std::pair0, 0.0) d_0, 0.0; 【参考方案1】:

这是标准的预期行为,还是编译器不完全支持的情况?

是的,这是预期行为。 [dcl.type.class.deduct] 阅读:

如果推导的类类型的占位符在初始化声明 ([dcl.init]) 的 decl-specifier-seq 中显示为 decl-specifier 一个变量,[...]

推导类类型的占位符也可以用在 new-type-idtype-idtype-specifier-seq /em> 的 new-expression,或作为显式类型转换(函数式表示法)中的 simple-type-specifier推导类类型的占位符不得出现在任何其他上下文中

非静态数据成员不是变量,我们不在其他情况下。

请注意,对于尝试使用auto 声明的非静态数据成员也是如此:

struct X 
    auto y = 0; // error
;

默认的成员初始化器就是这样 - 默认初始化器。如果你提供了一个构造函数,用不同类型的表达式初始化成员怎么办?

【讨论】:

至于委员会的预期行为,论文提案说“变量(或变量模板)的简单声明,它们也是声明符是 noptr-declarator 的定义(即,不是在声明函数时,模板参数、函数参数、非静态数据成员、指针、引用等)”。

以上是关于类数据成员中可以使用模板参数推导吗?的主要内容,如果未能解决你的问题,请参考以下文章

模板别名、变量模板和自动类型推导无法推导模板参数

在成员数据中使用模板参数的模板类的基类指针

模板之类模板

C++类模板常见用途和注意实现

c++创建链表为啥要用类模板

C++模板详解