此代码是否会导致违反一个定义规则



我试图弄清楚以下代码在什么情况下可能会违反一个定义规则。

页眉.h

#pragma once
#include <cstddef>
template<typename T, typename U>
class C {
 friend std::size_t f() {
  // Uses the template parameter that doesn't change
  return sizeof(T); 
 }
 friend std::size_t g() {
  // Uses the template parameter that does change
  return sizeof(U);
 }
 friend std::size_t h() {
  // Does not refer to template parameters
  return 0;
 }
};
// Declarations to help name lookup
std::size_t f();
std::size_t g();
std::size_t h();

src1.cpp

#include "header.h"
// Cause definintion of f(), g() and h()
template class C<int, double>;

src2.cpp

#include "header.h"
// Cause definintion of f(), g() and h()
template class C<int, float>;

我已经在两个不同的翻译单元中显式实例化了C类模板的两个不同版本。如果我将翻译单元链接在一起,我是否存在ODR违规行为?

g()显然会违反ODR,因为它在每个翻译单元中都有不同的实现。

但是f()h()呢?每个的实现(即令牌流(在翻译单元之间将保持不变。但它们都隐含地使用了C的不同实例化。这有什么不同吗?这里没有名字查询,是吗?

定义为友元声明一部分的函数隐式地是内联函数,因此只要所有翻译单元中的所有定义都相同,就不存在ODR冲突。它不是它的朋友类的成员,而是一个全局函数,类似于将函数声明为朋友,然后在类的定义完成后定义内联函数。

h不依赖于任何模板参数,而f依赖于模板参数,但该参数在您的示例中具有相同的类型(int(。

函数g在src1.cpp和src2.cpp中有不同的定义,因此这是潜在的ODR冲突。如果函数在两个翻译单元中都使用ODR,则会导致程序格式错误(无需诊断(

相关内容

  • 没有找到相关文章

最新更新