2015-01-02 60 views
3

我在理解N3638中描述的auto類型說明符的C++ 14擴展如何實現以及允許的內容方面有些困難。使用返回在另一個翻譯單元中定義的佔位符類型的函數

具體變化爲標準人說,

如果函數的聲明的返回類型包含的佔位符類型,函數的返回類型從return語句中的身體推導功能,如果有的話。

當函數的主體與聲明位於同一個文件中時,很容易看出它是如何工作的;但考慮一下頭文件聲明使用auto佔位符的方法但未定義它的情況。包含此頭文件但包含而非的翻譯單元如何包含定義成功編譯該方法的文件?

例如,給定文件foo.hpp

class foo 
{ 
    public: 
    auto gen_data(); 
}; 

...和文件foo.cpp

struct data_struct 
{ 
    int a; 
    int b; 
    int c; 
    double x; 
    char data[37]; 
}; 

auto foo::gen_data() 
{ 
    data_struct d; 
    // initialize members in d... 
    return d; 
} 

...和文件main.cpp

#include "foo.hpp" 

template<typename T> 
double get_x(T f) 
{ 
    return f.gen_data().x; 
} 

int make_and_get_x() 
{ 
    foo f; 
    return get_x<foo>(f); 
} 

...自行編譯main.cpp是合法的嗎?如果不是,爲什麼不呢?如果是這樣,get_x如何實例化,因爲編譯器無法知道gen_data的返回類型是否有名爲x的成員,更不用說它的偏移是什麼了?

這似乎是即使不擔心模板實例化也是一個問題;例如,如果您嘗試直接訪問f.gen_data().x或將它傳遞給函數會發生什麼?

+2

這是不合法的,因爲編譯器必須在需要它的每個翻譯單元(包含函數調用的表達式的類型)中推導出返回類型。但是,我不確定如何從標準中推斷出這一點。 – dyp

回答

2

的可適用的規則中§7.1.6.4[dcl.spec.auto]/P11發現:

如果需要 實體與undeduced佔位符類型的類型來確定的類型表達,該方案是格格不入。

這裏有一個例子:

auto f(); 
void g() { &f; } // error, f’s return type is unknown 

您需要的gen_data的類型來決定表達x.gen_data()的類型;因此該計劃不合格。要使用這樣的函數,定義必須對編譯器可見。

+0

是否有任何證據表明扣除需要由「編譯器」/在需要返回類型的翻譯單元中執行?那太好了。 – dyp

+0

@dyp我不太確定我理解這個問題...... –

相關問題