2012-03-07 42 views
1

我爲旋轉拍攝boost::operators(clang 2.1,boost 1.48.0),並遇到以下行爲,我無法解釋。看來,當我將我自己的operator double() const方法添加到我的類Ex(因爲我希望我的用戶在我的類的實例上使用static_cast<double>())時,我不再在嘗試在不相似的類之間使用operator==時發生編譯器錯誤。實際上,operator==似乎根本沒有被調用。來自boost :: operators的意外行爲

沒有operator double() const,該類完全按預期工作(除了它現在缺少轉換運算符),並且在嘗試f == h時收到正確的編譯器錯誤。

那麼添加這個轉換操作符的正確方法是什麼?下面的代碼。

// clang++ -std=c++0x boost-operators-example.cpp -Wall -o ex 
#include <boost/operators.hpp> 
#include <iostream> 


template <typename T, int N> 
class Ex : boost::operators<Ex<T,N>> { 
public: 
    Ex(T data) : data_(data) {}; 
    Ex& operator=(const Ex& rhs) { 
    data_ = rhs.data_; 
    return *this; 
    }; 
    T get() { 
    return data_ * N; 
    }; 
    // the troubling operator double() 
    operator double() const { 
    return double(data_)/N; 
    }; 
    bool operator<(const Ex& rhs) const { 
    return data_ < rhs.data_; 
    }; 
    bool operator==(const Ex& rhs) const { 
    return data_ == rhs.data_; 
    }; 
private: 
    T data_; 
}; 

int main(int argc, char **argv) { 
    Ex<int,4> f(1); 
    Ex<int,4> g(2); 
    Ex<int,2> h(1); 

    // this will fail for obvious reasons when operator double() is not defined 
    // 
    // error: cannot convert 'Ex<int, 4>' to 'double' without a conversion operator 

    std::cout << static_cast<double>(f) << '\n'; 


    std::cout 
    // ok 
    << (f == g) 

    // this is the error I'm supposed to get, but does not occur when I have 
    // operator double() defined 
    // 
    // error: invalid operands to binary expression 
    // ('Ex<int, 4>' and 'Ex<int, 2>') 
    // note: candidate function not viable: no known conversion from 
    // 'Ex<int, 2>' to 'const Ex<int, 4>' for 1st argument 
    // bool operator==(const Ex& rhs) const 
    << (f == h) 
    << '\n'; 
} 

回答

5

您應該將您的operator double()標記爲顯式。這允許靜態轉換,但是當您測試相等性(和其他情況下)時,防止它被用作隱式轉換。

+0

謝謝,這工作。你能否更詳細地解釋一下編譯器如何認爲平等測試適用於隱式轉換? – 2012-03-07 14:49:09

+2

當編譯器執行重載解析時,它包含內置的運算符 - 包括'operator ==(double,double)'。並且允許爲每個參數使用一個隱式轉換,以便一個是有效的候選。並沒有更好的選擇,所以它被選中。 – 2012-03-07 15:53:20

+1

有關隱式轉換(轉換運算符和構造函數)的事情是它們是隱含的。有一個你幾乎說你的類型相當於一個雙。這在您需要時很有用,但通常最好保持轉換明確。 – 2012-03-07 15:56:05