2013-02-22 92 views
1

級聯類型轉換時,如何獲得類型轉換才能工作?C++級聯類型轉換

下面的代碼應該很簡單,但是從TypeB到int的轉換需要編譯器自動推導出兩種類型的轉換。但事實並非如此。

我不能簡單地實現 operator int()const {return val; } TypeB類,因爲這應該是一個模板類我不知道要轉換爲哪種類型。

class TypeA { 
public: 
    TypeA(int a) : val(a) {} 
    operator int() const { return val; } 
private: 
    int val; 
}; 

class TypeB { 
public: 
    TypeB(TypeA a) : val(a) {} 
    operator TypeA() const { return val; } 
    // operator int() const { return val; } // Explicit conversion to int which I can not know. 
private: 
    TypeA val; 
}; 

void main() { 
    TypeA a = 9; 
    TypeB b = a; 
    int int_a = a; 
    TypeA a2 = b; 
    int int_b = b; // Compilation error: 
        // No suitable conversion function from 'TypeB' to 'int' exists 
} 

問候

回答

0

那麼你想TypeB<T>使用用戶定義的轉換T

創建使用SFINAE檢查的T轉換操作符和接受時U是一種T有一個operator U模板operator U

一個不充分但簡單的方法是std::is_convertible - 地址T::operator U可能更好。

這需要C++ 11功能才能合理完成,因爲您需要在默認模板參數中使用enable_if

這是一個粗略的實現:我沒有介紹具有構造函數的源類型的目標類型。

#include <utility> 
#include <type_traits> 
#include <iostream> 

struct A { 
    operator int() { return 7; } 
}; 

template<typename T> 
struct unevaluated: std::true_type {}; 

template<typename T, typename U, typename=void> 
struct has_user_defined_conversion:std::false_type {}; 

template<typename T, typename U> 
struct has_user_defined_conversion<T, U, 
    typename std::enable_if< unevaluated< 
    decltype(
     &T::operator U 
    ) 
    >::value >::type 
>: std::true_type {}; 

template<typename T> 
struct fake { 
    T t; 
    template<typename U, 
    typename=typename std::enable_if<has_user_defined_conversion<T,U>::value>::type 
    > 
    operator U() { return t; } 
}; 

int main() { 
    int x = fake<A>(); 
    std::cout << x << "\n"; 
} 
3

在任何隱式轉換序列你至多一個隱式用戶定義的轉換允許

但是,您可以說int int_b = static_cast<TypeA>(b);可以使UDC的數量降至1。