[英]Template with auto-type return deduction
我創建了一個模板化的結構,並試圖重載二元運算符。 由於某種原因,即使在兩者之間正確地輸入類型,該函數也不會返回正確的數據類型。
template<typename T>
struct Number{
const T value;
Number(T a) : value(a) {}
template<typename U>
auto operator*(Number<U> other){
auto new_value = value*other.value;
std::cout << typeid(new_value).name() << std::endl;
return Number(new_value);
}
};
現在,如果我使用main中調用的以下代碼執行此操作。 它返回第一個類型的Number,而不是更高類型的數字。
auto b = Number<int>(6) * Number<double>(2.3); // this should be an int*double=double
std::cout << b.value << typeid(b.value).name() << std::endl;
auto c = Number<double>(2.3) * Number<int>(6);
std::cout << c.value << typeid(c.value).name() << std::endl;
輸出如下:d 13i d 13.8d
據我所知,當函數返回新的Number(new_value)
時,會調用錯誤的構造函數。 我不明白為什么會發生這種情況以及為什么會發生這種情況,因為new_value屬於'正確的類型'。
在模板范圍內,template-name將代表注入的類名,而不是模板。 所以不會有CTAD, 這是設計的
使用return Number<decltype(new_value)>(new_value);
是一個簡單的解決方法。
您將返回第一種類型而不是第二種類型:
template<typename U>
auto operator*(Number<U> other){
auto new_value = value*other.value;
std::cout << typeid(new_value).name() << std::endl;
return Number(new_value);
}
即使new_value
是double,您也將它存儲在Number<T>
。
嘗試:
template<typename U>
auto operator*(Number<U> other){
auto new_value = value*other.value;
std::cout << typeid(new_value).name() << std::endl;
return Number<decltype(new_value)>(new_value);
}
正如StoryTeller所指出的,在類模板定義中,類的名稱是指特定的類實例(稱為inject-class-name )而不是模板的名稱。
但是,如果您仍希望應用類模板參數推導,則可以限定名稱:
return ::Number(new_value);
::Number
是指類模板Number
,而不是特定類型Number<T>
。 但是對於閱讀代碼的其他人來說,這可能有點Number<decltype(new_value)>(new_value)
,只需使用Number<decltype(new_value)>(new_value)
有很多好處。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.