gpt4 book ai didi

c++ - 为什么显式模板实例化不会破坏 ODR?

转载 作者:太空狗 更新时间:2023-10-29 21:33:08 25 4
gpt4 key购买 nike

这个问题出现在 this answer 的背景下.

如我所料,这个翻译单元无法编译:

template <int Num> int getNum() { return Num; }
template int getNum<0>();
template int getNum<0>(); // error: duplicate explicit instantiation of 'getNum<0>'
int main() { getNum<0>(); return 0; }

我明白这一点,我曾尝试两次进行相同的显式模板实例化。然而,事实证明,将它分成不同的单元,它编译:

// decl.h
template <int Num> int getNum() { return Num; }

// a.cc
#include <decl.h>
template int getNum<0>();

// b.cc
#include <decl.h>
template int getNum<0>();
int main() { getNum<0>(); return 0; }

没想到会这样。我假设具有相同参数的多个显式模板实例化会破坏 ODR,但情况似乎并非如此。然而,这确实失败了:

// decl.h
template <int Num> int getNum();

// a.cc
#include "decl.h"
template <> int getNum<0>() { return 0; }

// b.cc
#include "decl.h"
template <> int getNum<0>() { return 0; }
int main() { getNum<0>(); return 0; }

用户 Oliv帮助我指向 this relevant paragraph in the standard , 但我对此仍然有些困惑,所以我希望有人能用更简单的术语解释这背后的逻辑(例如,什么应该或不应该被认为会破坏 ODR,以及为什么我的期望是错误的)。

编辑:

作为进一步的例子,这里有一个程序分为两个单元,编译正确但它产生了可以说令人惊讶的结果:

// a.cc
template <int Num> int getNum() { return Num + 1; }
template int getNum<0>();

// b.cc
#include <iostream>
template <int Num> int getNum() { return Num; }
template int getNum<0>();
int main() { std::cout << getNum<0>() << std::endl; return 0; }

输出:

1

在这种情况下,删除显式模板实例会产生 0。我知道拥有两个具有不同定义的模板不是常见的用例,但我认为 ODR 是为了避免此类问题而严格执行的。

最佳答案

Eureka !我终于落在了相关段落上,[temp.spec]/5

For a given template and a given set of template-arguments,

  • (5.1) an explicit instantiation definition shall appear at most once in a program,

  • (5.2) an explicit specialization shall be defined at most once in a program, as specified in [basic.def.odr], and

  • (5.3) both an explicit instantiation and a declaration of an explicit specialization shall not appear in a program unless the explicit instantiation follows a declaration of the explicit specialization.

An implementation is not required to diagnose a violation of this rule.

因此显式模板实例化定义(而非隐式实例化)可能导致 ODR 违规,不需要诊断(至少 gcc 和 clang - ld 工具链不产生诊断)

关于c++ - 为什么显式模板实例化不会破坏 ODR?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52664184/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com