2011-10-03 86 views
20

'std :: piecewise_construct',在<實用程序>中定義,因爲它被聲明爲constexpr而具有內部鏈接。我想知道在標題中使用'std :: piecewise_construct'是否會違反ODR。例如:不是std :: piecewise_construct導致ODR違規?

// a.hpp 
#include <utility> 
#include <tuple> 

struct point 
{ 
    point(int x, int y) 
     : x(x), y(y) 
    {} 

    int x, y; 
}; 

inline std::pair<point, point> f(int x1, int y1, int x2, int y2) 
{ 
    return { 
     std::piecewise_construct, 
     std::forward_as_tuple(x1, y1), std::forward_as_tuple(x2, y2) 
    }; 
} 

// translation unit 1 
#include "a.hpp" 

// translation unit 2 
#include "a.hpp" 

在TU 1 f的「標準:: piecewise_construct」是指在TU 2「F」不同的對象比我懷疑「F」違反ODR。

N3290(可能ISO/IEC 14882:2011也)表示以下情況下是ODR的一個例外,在3.2/5:

的名稱可以指const對象與內部或沒有連鎖,如果該對象在D的所有定義中都具有相同的文字類型,並且該對象使用常量表達式(5.19)進行初始化,並且使用該對象的值(但不是地址),並且該對象具有相同的值D的定義;

「F」滿足幾乎所有的要求,但「使用值的對象(而不是地址)」,似乎模棱兩可給我。確實'std :: piecewise_construct_t'沒有狀態,但'std :: pair'的分段構造函數的調用涉及對'std :: piecewise_construct_t'的隱式聲明拷貝構造函數的調用,其參數是'const std :: piecewise_construct_t &'。地址是「使用」的,不是嗎?

我很困惑。

參考:http://lists.boost.org/Archives/boost/2007/06/123353.php

+2

+1(我認爲)對於一個問題,仍然有我沒有線索2分鐘後 – sehe

+0

這不是與'std :: cout'相同的問題? –

+1

@Kerrek'std :: cout'沒有多次定義。它只是在其各自的頭文件中聲明。 –

回答

6

看來,你已經在提升郵件列表中你的答案。是的,我認爲這是未定義的行爲,或者至少沒有明確定義的行爲。

請參閱this usenet discussion討論同一事項。

+0

謝謝你的回答。 – iorate

+0

我也這麼認爲。順便說一句,與Boost不同,標準庫不需要僅用於標題。因此'piecewise_construct'應該被聲明爲:'extern const piecewise_construct_t piecewise_construct;'。我想知道爲什麼它不是。 – iorate

+0

我建議詢問comp.std.C++或comp.lang.C++。moderated。 –

0

恕我直言,在ODR下沒有衝突。

未命名的名稱空間與標記內部鏈接(靜態)的效果具有相同的效果。 這確實意味着每個TU都使用他自己的這種類型/功能的唯一定義。

我看他們的樣子,佔位符(:::: _ 1和競爭的味道)是如何工作的,不能被實例化這麼多的編譯時類型推斷:

_1,_2等僅僅是佔位符,並且它們並不需要兼容(值不需要從一個TU傳遞到另一個,它們僅作爲類型推斷的參數傳遞,並且因此它們的實際類型被推斷爲具有identity來自當前TU的)。

IOW:您可以通過專門化一些特性來輕鬆定義自己的佔位符,並且它們仍然應該像魅力一樣工作。

namespace boost 
{ 
    template<int I> struct is_placeholder< 
      my_funny_own_placeholder_no_ODR_involved<I> > 
    { 
     enum _vt { value = I }; 
    }; 
} 

我想同樣的邏輯可以適用於piecewise_construction(但我沒有看太多)。

+0

'問題'是當考慮兩個TU時,'f'的相應定義是不同的,因爲它們不引用相同的'std :: piecewise_construct'並且使用地址,而不是該值。因此,潛在的ODR違規是每個TU中「f」可能不同。由Johannes鏈接的討論中提供了更多信息。 –

+0

@LucDanton:這是一個怎樣的問題?它們在不同的未命名的命名空間中只是不同的功能?請注意,我主要是基於關於_1,_2 ...佔位符的鏈接討論。我將閱讀關於分段鏈接的討論......稍後 – sehe

+0

'f'不在未命名的名稱空間中。如果是的話,你是對的,這不會有問題。 –

相關問題