为什么这不违反一个定义规则?

Why does this not violate One definition rule?

我是 c++ 的新手,正在尝试理解单一定义规则。在多个 c++ 文件中包含以下 test.h 文件会破坏单一定义规则(syspath 和标签)。如果不是,为什么不呢?

 #ifndef TEST_H
 #define TEST_H_

#include <string>
#include <unordered_set>

namespace X {

class Test {
  public:
     // Default constructor.
     Test();
     ~Test();

     const std::string& syspath() const { return syspath_; }
     const std::unordered_set<std::string> tags() const { return tags_;}
   private:
     std::string syspath_;
     std::unordered_set<std::string> tags_;
};

}  // namespace X

#endif  // TEST_H_

syspathtags 不是对象或非内联函数,因此 ODR 不适用于它们。类型的 ODR 间接适用于它们(因为它们是类型 X::Test 的一部分),但只要它们(和 X::Test)在每个编译单元中都相同,它们就没问题。

wikipedia page 所述,ODR 有两个相关但不同的部分——一个适用于编译单元内的模板、类型、函数和对象,另一个适用于对象和非跨编译单元的内联函数。

ODR 允许 class 的多个定义以及内联函数的定义,只要所有定义都相同,并且每个定义都在单独的翻译单元中。 header 警卫满足后一个要求(或者如果没有打字错误的话)。

class 定义仅声明数据成员。这些不是变量定义。 ODR 允许无限制声明。

在构造 class 的实例之前,不存在成员变量的实例,并且 class 的每个实例都包含一个单独的变量实例。

如果此 header 包含在多个翻译单元中,则不违反 ODR。