1

级联类型转换时如何使类型转换工作?

下面的代码应该很简单,但是从 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
}

问候

4

2 回答 2

3

在任何隐式转换序列中,最多允许一次隐式用户定义转换。

不过,您可以说int int_b = static_cast<TypeA>(b);将 UDC 的数量减少到一个。

于 2013-02-22T12:58:27.840 回答
0

所以你想TypeB<T>使用用户定义的转换T

创建一个模板,该模板operator U使用 SFINAE 检查转换运算符T并接受何时U是一个类型T具有一个operator Ufor。

一个不充分但简单的方法是std::is_convertible--address ofT::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";
}
于 2013-02-22T13:07:04.273 回答