在这种特殊情况下,为什么我不需要模板参数?

Gui*_*cot 9 c++ templates c++14

我有这个代码:

struct Base {};

template<typename T>
struct Foo : Base {};

struct Bar {
    template<typename T> //           v--- What's happening here?
    Bar(T foo) : baz{std::make_unique<Foo>(foo)} {}

    std::unique_ptr<Base> baz;
};
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,GCC和Clang接受并编译了它.它似乎推断出模板参数Foo,但它没有意义.为什么编译器接受即使没有重载std::make_unique需要模板模板参数呢?Live example

Bri*_*ian 8

在某些情况下,模板始终无效,无论提供什么模板参数,但编译器都无法解决这个问题,因为它无法尝试替换每个可能的模板参数集.根据标准([temp.res]/8):

如果无法为模板生成有效的专业化,并且未实例化该模板,则模板格式错误,无需诊断.

这意味着允许编译器是智能的,并证明没有有效的特化,并产生编译错误,但它也被允许不够智能,并且不会产生编译错误.当然,一旦模板被实例化,那么编译器必须诊断错误.

在没有模板参数的情况下使用模板名称并不违法.在某些情况下,编译器可以推断出参数.例如:

template <class T>
void foo(T x);

int main() {
    void (*p)(int) = foo;  // p points to foo<int>
}
Run Code Online (Sandbox Code Playgroud)

在您的代码中,事实证明您已经Foo在无法推导出模板参数的上下文中使用过.如果编译器更聪明,他们就会想出来.但他们没有设法解决这个问题的事实并不意味着你的代码是正确的.