c – 为什么在这种情况下我不需要模板参数?

我有这个代码
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;
};

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

解决方法

在某些情况下,模板总是无效的,无论提供什么样的模板参数,但编译器无法弄清楚,因为它无法尝试替换每个可能的模板参数集.根据标准([temp.res] / 8):

If no valid specialization can
be generated for a template,and that template is not instantiated,the template is ill-formed,no diagnostic
required.

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

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

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

int main() {
    void (*p)(int) = foo;  // p points to foo<int>
}

在你的代码中,原来你已经在不能推导出模板参数的上下文中使用过Foo.如果编译器更聪明,那么他们就会想出来.但是他们没有想出来的事实并不意味着你的代码是正确的.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...