2013-02-22 91 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。