考慮粘貼在下面的代碼。我已經定義了一個非常簡單的類,爲此編譯器生成一個隱式演繹指南,因此它可以在沒有顯式模板參數的情況下構建。但是,模板參數推導不工作從只直接轉發到目標類的簡單的別名模板構造一個對象:類別模板參數扣除不與別名模板一起使用
template< typename A, typename B >
struct Foo {
Foo(A const &a, B const &b)
: a_(a), b_(b)
{ }
A a_;
B b_;
};
template< typename A, typename B >
using Bar = Foo<A, B>;
auto foobar() {
Foo r{1, 2};
Bar s{3, 4};
// ../src/geo/vector_test_unit.cpp: In function 'auto foobar()':
// ../src/geo/vector_test_unit.cpp:16:6: error: missing template arguments before 's'
// Bar s{3, 4};
// ^
return 1;
}
正如你可以從上面的代碼註釋看,G ++是給我有關使用沒有模板參數的別名模板的錯誤。我希望在這種情況下,模板論證扣除將被轉發。
那麼,我的問題:這是通過明確設計類模板參數演繹提案的當前措詞嗎?或者,這是該功能的當前g ++實現中未完成的功能或缺陷?這對於提案的作者或者C++ ISO委員會來說可能是一個更大的問題,但是如果他們中的任何一個人看到這樣的話:這個特性的最後措辭是否包括啓用別名模板也是理想的爲他們生成隱式指南?
我可以理解,由於別名模板可以具有任何類型的模板參數,因此編譯器可能無法總是成功推導出目標類模板參數,但在這種情況下,我希望編譯器會是能夠以同樣的方式直接爲目標課程。
我在前幾天使用gcc構建gcc,使用--std=c++1z
。完整版本信息是:gcc version 7.0.0 20161201 (experimental) (Homebrew gcc HEAD- --with-jit)
我一次建立並編譯您的示例文件,試圖逐步瞭解它。我只用#1,#2和行int * x編譯了它; Q p = x;'。正如你所指出的,它會給出一個錯誤,除非我刪除#2並重新編譯。來自g ++的錯誤信息是'[...]錯誤:從'int *'到'int'的無效轉換... Q p = x; ...注意:初始化'Q :: Q(T)[with T = int]'參數1'template struct Q {Q(T); };'。對我來說,就像你說的那樣,它試圖使用#2而不是#1。我不瞭解什麼? –
@squidbidness對於類模板參數推導,'Q p = x;'這一行使用#1推導'p'的類型爲'Q'。選擇該類型後,它推斷'Q '應該使用'Q '部分專業化,推導出'T = int'。最後,它試圖調用一個'Q '構造函數,其參數類型爲'int *',因爲唯一的構造函數(默認/複製/移動ctors除外)需要一個int類型,所以它不起作用。 –
謝謝你的澄清。讓我感到困惑的部分是我的心智模型已經推導出'p'的類型,並且選擇一個模板專業化作爲一個相同的過程。指出他們是單獨的步驟幫助我更好地推理它。 –