扩展版在这里。
我们可以创建具有默认模板参数的类模板对象,而无需键入尖括号:
int main()
{
std::less a;
}
Run Code Online (Sandbox Code Playgroud)
但是对于成员变量我们不能这样做:
struct S
{
std::less a; // I want only type std::less<void> here
};
Run Code Online (Sandbox Code Playgroud)
看起来第一种情况由于CTAD起作用,但为什么编译器不能std::less<void>在第二种情况下推断?也许我们不应该在那里应用 CTAD,而是提供不同的机制。
这是否被认为是标准中的错误?有没有修复它的建议?
我的用例:
我有一个提供默认参数的类模板,如下所示:
template <typename T = int>
class Foo {};
Run Code Online (Sandbox Code Playgroud)
模板参数是我自己从未使用过的专家专用功能,但它适用于那些想要完全灵活性的 1% 的专家。现在对于其他 99% 我想隐藏Foo实际上是类模板但它不起作用的事实,因为用户在将Foo<>其声明为成员变量时必须键入,当前的解决方案是:
template <typename T = int>
class BasicFoo {};
using Foo = BasicFoo<>;
Run Code Online (Sandbox Code Playgroud)
但它使实现代码复杂化,一点也不优雅。
不,这不是错误。这是因为同一个成员变量(通过类的构造函数初始化列表调用)可能会调用不同的构造函数,从而可能产生不同的推导结果。
为了防止这种冲突的可能性,您必须为非静态成员提供模板参数。(静态成员不是问题,因为它们将有一个构造函数调用)