簡體   English   中英

可以使用不同的別名模板來解決跨庫的潛在ODR違規問題嗎?

[英]Can differing alias templates resolve potential ODR violations across libraries?

我在大型代碼庫中發生了潛在的ODR違規。 它是一個類模板,可以根據不同庫中的#ifdef切換行為,但沖突的lib可能使用模板的不同實例。 作為簡化示例:

// foo.h
#ifdef USE_DOUBLE
template <typename T>
struct foo { T* value; double x; };
#else
template <typename T>
struct foo { T* value; };
#endif

struct c;

// a_lib.cpp
#include "foo.h"
struct a { foo<a> m_a; };
struct a_helper { foo<c> m_c; };

// b_lib.cpp
#define USE_DOUBLE
struct b { foo<b> b; };
struct b_helper { foo<c> m_c; };
  1. 我猜foo<a>foo<b>沒有ODR違規,對嗎?
  2. 但是a_helperb_helper帶來的foo<c>的不同定義只是非常粗略,正確嗎?

問題是我在一個巨大的項目中有這個。 此外,我可能(但不確定)我只有相當於非重疊的ab ,而不是有問題的a_helperb_helper 但是,我真的不能確定。

我想知道我是否可以通過將foo更改為別名模板來避免此問題:

template <typename T>
struct foo_double_impl { T* value; double x; };

template <typename T>
struct foo_impl { T* value; };

#ifdef USE_DOUBLE
template <typename T>
using foo = foo_double_impl<T>;
#else
template <typename T>
using foo = foo_impl<T>;
#endif
  1. 現在,我們現在有了foo_impl和foo_double_impl的定義,而不是兩個不同的foo定義。 這是否解決了ODR違規問題? 或者ODR違規是否仍然存在,因為foo有兩個不同的別名模板?

ODR 在標准中指定相當長,歸結為說你必須

  • 只有一個非內聯函數或變量的定義
  • 至少有一個其他所用的定義。 大量定義必須完全相同 ,包括
    • 擁有相同的令牌序列
    • 令牌的順序意味着同樣的事情
    • 讓相應令牌的所有查找都找到相同的東西

歸納起來,他們真的真的要在所有可能的方式是相同的。

在所有場景中, foo通過使用不同的令牌序列來違反ODR。


不改變庫的最佳修復是內聯命名空間

#ifdef USE_DOUBLE
inline
#endif
namespace D {
    template <typename T>
    struct foo { T* value; double x; };
} 

#ifndef USE_DOUBLE
inline
#endif
namespace ND {
    template <typename T>
    struct foo { T* value; };
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM