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


C ++ 17介绍 模板参数推导

使用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 通过。

我尝试了其他一些组合,但似乎都没有。

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

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


9123
2017-11-20 18:02


起源

我不确定你到底在问什么。标准可以要求行为,委员会可以打算行为。你的意思是:1)标准所要求的行为,或者你的意思是2)C ++委员会的行为? - Johannes Schaub - litb
@ JohannesSchaub-litb问题是相当清楚,询问它是否符合标准或编译器错误的正确行为。 - Barry
可能的解决方法: decltype(std::pair{0, 0.0}) d_{0, 0.0}; - W.F.


答案:


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

是的,这是预期的行为。 [dcl.type.class.deduct] 内容如下:

如果推断的类类型的占位符显示为 DECL说明符 在里面 DECL说明符-SEQ 初始化声明([dcl.init])的 一个变量,[...]

推导类类型的占位符也可用于 类型说明符-SEQ 在里面 新型-ID 要么 类型ID 一个 新的表达或者作为 简单型说明符 在显式类型转换(功能表示法)中。 推断类类型的占位符不应出​​现在任何其他上下文中

非静态数据成员不是变量,我们处于其他任何情况。

请注意,对于尝试声明的非静态数据成员,同样的原则也适用 auto

struct X {
    auto y = 0; // error
};

默认的成员初始化程序就是 - 默认的初始化程序。如果您提供了使用不同类型的表达式初始化成员的构造函数,该怎么办?


9
2017-11-20 18:09



至于委员会的预期行为,论文提案说“变量(或变量模板)的简单声明,也是声明者是noptr-declarator的定义(即在声明函数,模板参数,函数参数,非静态时)数据成员,指针,参考文献等)“。 - Johannes Schaub - litb