2011-10-03 28 views
20

'std :: piecewise_construct', được định nghĩa trong tiện ích < >, có liên kết nội bộ vì nó được khai báo constexpr. Tôi tự hỏi, nếu sử dụng 'std :: piecewise_construct' trong một tiêu đề có thể vi phạm ODR. Ví dụ:Không std :: piecewise_construct gây ra vi phạm 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" 

Các 'std :: piecewise_construct' trong 'f' trong TU 1 đề cập đến một đối tượng khác nhau hơn so với trong 'f' trong TU 2. Tôi nghi ngờ 'f' vi phạm ODR.

N3290 (có thể là ISO/IEC 14882: 2011 cũng) cho biết trường hợp sau đây là một ngoại lệ của ODR, trong 3,2/5:

một tên có thể tham khảo một đối tượng const với nội hoặc không có mối liên hệ nếu đối tượng có cùng kiểu chữ trong tất cả các định nghĩa của D và đối tượng được khởi tạo với một biểu thức không đổi (5.19) và giá trị (nhưng không phải địa chỉ) của đối tượng được sử dụng và đối tượng có cùng giá trị trong tất cả định nghĩa của D;

'f' đáp ứng hầu hết các yêu cầu, nhưng "giá trị (nhưng không phải địa chỉ) của đối tượng được sử dụng" có vẻ mơ hồ đối với tôi. Đúng là 'std :: piecewise_construct_t' không có trạng thái, nhưng cuộc gọi của hàm khởi tạo piecewise của 'std :: pair' liên quan đến cuộc gọi của hàm tạo bản sao được khai báo ngầm của 'std :: piecewise_construct_t', đối số của nó là 'const std :: piecewise_construct_t & '. Địa chỉ được "sử dụng", phải không?

Tôi rất bối rối.

Tham chiếu: http://lists.boost.org/Archives/boost/2007/06/123353.php

+2

+1 (Tôi nghĩ) cho một câu hỏi vẫn còn có tôi mà không có một đầu mối sau 2 phút – sehe

+0

Đây không phải là vấn đề tương tự với 'std :: cout'? –

+1

@Kerrek 'std :: cout' không được xác định nhiều lần. Nó chỉ được khai báo trong các tiêu đề tương ứng của nó. –

Trả lời

6

Dường như bạn đã có câu trả lời trong danh sách gửi thư tăng cường đó. Có, theo ý kiến ​​của tôi nó là hành vi không xác định hoặc ít nhất là không đủ rõ ràng hành vi được xác định.

Xem this usenet discussion cho cùng một vấn đề đang được thảo luận.

+0

Cảm ơn bạn đã trả lời. – iorate

+0

Tôi cũng nghĩ như vậy. Bằng cách này, không giống như Boost, không cần thư viện chuẩn là chỉ tiêu đề. Do đó 'piecewise_construct' nên được khai báo là: 'extern const piecewise_construct_t piecewise_construct;'. Tôi tự hỏi tại sao nó không phải vậy. – iorate

+0

Tôi khuyên bạn nên hỏi về comp.std.C++ hoặc comp.lang.C++. –

0

IMHO không có xung đột theo ODR.

Không gian tên không tên có tác dụng tương tự như đánh dấu mọi thứ cho liên kết nội bộ (tĩnh). Điều này thực sự có nghĩa là mỗi TU sử dụng định nghĩa duy nhất của riêng mình cho các loại/chức năng như vậy.

Con đường tôi nhìn vào họ, làm thế nào giữ chỗ (:::: _ 1 và cạnh tranh hương vị) làm việc, không phải là bởi instantiation quá nhiều như bởi compiletime suy luận kiểu:

_1, _2 vv có chứa đơn thuần và chúng không thực sự cần tương thích (các giá trị không cần phải chuyển từ TU sang loại khác, chúng chỉ được chuyển thành loại tham số được phỏng đoán và như vậy loại thực tế của chúng được phỏng đoán là có identity từ TU hiện tại).

IOW: Bạn có thể dễ dàng xác định trình giữ chỗ của riêng mình bằng cách chuyên một số đặc điểm và chúng vẫn hoạt động như một nét duyên dáng.

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

Tôi giả sử cùng một logic có thể giữ cho piecewise_construction (nhưng tôi chưa xem xét nhiều).

+0

'Vấn đề' là khi xem xét cả hai TU, các định nghĩa tương ứng của 'f' khác nhau vì chúng không tham chiếu cùng một' std :: piecewise_construct' và địa chỉ được sử dụng, không phải giá trị. Do đó, vi phạm ODR tiềm năng là 'f' có thể khác nhau trong mỗi TU. Thông tin thêm có sẵn trong cuộc thảo luận được liên kết bởi Johannes. –

+0

@LucDanton: vấn đề đó như thế nào? Chúng chỉ là các chức năng khác nhau trong các không gian tên không tên khác nhau? Lưu ý rằng tôi chủ yếu dựa vào thảo luận được liên kết về các trình giữ chỗ _1, _2 .... Tôi sẽ đọc vào các cuộc thảo luận liên kết về piecewise ... sau – sehe

+0

'f' không có trong một không gian tên không tên. Nếu đúng, bạn đã chính xác sẽ không có vấn đề gì. –

Các vấn đề liên quan