這是一個非常難以找到的細微錯誤的例子,這是由非直觀類型推理引起的。程序員希望「var2」是NewValue()函數中模板參數類型推導的類型「derived2」。實際發生的是var2的推導類型是 基類「derived1」。如果您在派生類中重寫了ConvertValue()虛函數,則它將編譯並按預期工作。從虛擬成員函數ptr中刪除類型(bug?)
爲了演示類型不匹配,我放入編譯器斷路器行。問題在於,許多地方使用NewValue <>,這些地方的意外類型演繹乾淨地傳遞給了意想不到的結果。 此外,程序員希望能夠繼承基類成員函數「ConvertValue()」,而不必在每個派生類中重載它,只是爲了讓NewValue <>能夠按預期工作。
這是由編譯器正確解釋還是它是一個編譯器錯誤?
class base
{
int x;
public:
base() : x(10){}
int value() const { return x; }
void value(int val) { x = val; }
};
class derived1 : public base
{
public:
virtual void ConvertValue(int x) { value(Factor()*x); }
virtual int Factor() const { return 2; }
};
class derived2 : public derived1
{
public:
//virtual void ConvertValue(int x) { value(Factor()*x); }
virtual int Factor() const { return 3; }
};
template<typename T>
T NewValue(void (T::*unitsFunc)(int), int value)
{
T obj;
(obj.*unitsFunc)(value);
return obj;
}
int _tmain(int argc, _TCHAR* argv[])
{
auto var1 = NewValue(&derived1::ConvertValue, 10);
auto var2 = NewValue(&derived2::ConvertValue, 10);
std::cout << "Test type deduction from virtual member function" << std::endl << std::endl
<< "This should have value of 20: " << var1.value() << std::endl
<< "This should have value of 30: " << var2.value() << std::endl
<< (var2.value() == 30 ? "CORRECT" : "INCORRECT - bad type deduction") << std::endl << std::endl ;
// this will not compile because NewValue<>() is returning type "derived1" instead of "derived2"
derived2 test = NewValue(&derived2::ConvertValue, 10);
return 0;
}
是的,這麼想。我希望類型演繹的力量可以用來保持語法清晰。我將不得不思考一些替代方案,因爲這些東西在大型代碼庫中隨處可見。謝謝 – user2562278