首页 文章

何时需要实例化函数模板定义?

提问于
浏览
-4

在我读完这个答案之后,我仍然在问问题 . 答案讨论了[temp.point]中定义的实例化点的位置,但是如果实例化是必需的则不进行评估 .

[temp.inst]指定何时需要函数模板特化实例化,一般规则是:

除非需要进行此类实例化,否则实现不得隐式实例化函数模板,变量模板,成员模板,非虚拟成员函数,成员类[...] .

此外,在本标准的这一部分的某一段中,单独考虑了声明的实例化和定义的实例化 .

我们考虑一下这段代码:

static void Yeap0(int);

template <class T>
void Yeap(T a){
    Yop(a);
}

template <class T>
auto Yeap2(T a){
    Yop(a);
    return 0;
}
namespace x{
    struct y{};
}

int main() {
    Yeap0(0);//ok no definition required here
    x::y ax{};
    Yeap(ax); //the declaration is sufficient, 
    Yeap2(ax); //need to deduce auto => definition required
               //compilation error
    return 0;
}

namespace x{
    void Yop(y){}
}

static void Yeap0(int){}

Gcc,Clang和MSVC仅产生 Yeap2(ax) 的错误,抱怨_822640_未在Yeap2的实例化时定义 .

但是 Yeap(ax) 没有生成此错误 . 从基本考虑来看,这似乎是合乎逻辑的,只需要声明,就像无模板函数 Yeap0 一样 .

但是[temp.inst]/4的讲座让我感到困惑 . 可以理解,还需要 Yeap 的实例化 . 但似乎编译器采取了更聪明的方法 .

编译器行为是扩展吗?


注意:我不接受"no diagnostic required"答案 . 这将是对情报的侮辱:可以有人认为3个编译器特别注意关闭像 Yeap(ax) 这样的情况的诊断但不是 Yeap2(ax) 吗?

1 回答

  • 1

    编译器抱怨的确来自于函数返回 auto 的事实 .

    auto 案例中你确实遇到了

    除非需要进行此类实例化 .

    这必须来自要求dcl.spec.auto .

    要验证评估,您可以在代码中替换Yeap2:

    template <class T>
    auto Yeap2(T a){
        Yeap(a);
        return 0;
    }
    

    并且没有编译错误 .

相关问题