成员变量中的类模板参数推导

时间:2019-03-06 15:41:00

标签: c++ templates c++17

扩展版本here

我们可以创建具有默认模板参数的类模板对象,而无需输入尖括号:

int main()
{
    std::less a;
}

但是我们不能对成员变量执行此操作:

struct S
{
    std::less a; // I want only type std::less<void> here
};

由于CTAD,第一种情况似乎可行,但是为什么在第二种情况下编译器无法推断出std::less<void>?也许我们不应该在此应用CTAD,而应提供不同的机制。

这是否被视为标准中的错误?有修复建议吗?

我的用例:

我有一个提供默认参数的类模板,如下所示:

template <typename T = int>
class Foo {};

template参数是我自己从未使用过的仅专家功能,但对于希望获得总体灵活性的1%专家来说,它是可用的。现在,对于其他99%的人,我想掩盖一个事实,Foo实际上是一个类模板,但是它不起作用,因为用户在将其声明为成员变量时必须键入Foo<>,当前的解决方案是:

template <typename T = int>
class BasicFoo {};

using Foo = BasicFoo<>;

但是它使实现代码复杂化,而且一点也不优雅。

1 个答案:

答案 0 :(得分:3)

不,这不是bug。这是因为可能会有不同的构造函数调用同一个成员变量(通过类的构造函数init列表调用),从而可能得出不同的推论结果。

为避免潜在的此类冲突,您必须向非静态成员提供模板参数。 (静态成员不是问题,因为将有一个构造函数调用它们)