为什么这个嵌套模板推导会失败?

Why this nested template deduction should fail?

当我在玩模板时,我注意到一个奇怪的模板推导失败,我想知道为什么这在逻辑上应该失败。请检查此代码:

template<typename T = int>
struct A {
    T v;
};

int main()
{
    A k;
    static_assert(std::is_same_v<decltype(k.v), int>);
}

此代码编译没有任何问题,并且 k.v 将具有 int 类型,因为它被定义为模板参数的默认类型。现在这段代码:

template<typename T = int>
struct A {
    T v;
};

struct B {
    A a;
};

int main()
{
    A k;
    static_assert(std::is_same_v<decltype(k.v), int>);
}

此代码给出 B 的编译错误。因为在非静态结构成员中似乎不允许参数推导。但我不明白为什么。由于AAA模板有一个默认类型,它可以很容易地将B结构中的A成员视为A<int>。我想知道为什么这不会发生。有什么想法吗?

这段代码:

struct B {
    A a;
};

报错:

invalid use of template-name 'A' without an argument list

那是因为 A 是一个模板,因此编译器要求您使用它。即使 A 有默认参数也是如此;您仍然必须使用 <> 来表示您正在使用模板。

所以这段代码:

struct B {
    A<> a;   // note the <>
};

可以正常编译。

至于为什么模板参数不能为非静态数据成员推导,好像和这个不行的原因是一样的:

struct B {
  auto a = 0;  // error
}

有关详细信息,请参阅 this 问答。