Как заставить преобразование типов работать при каскадном преобразовании типов?
Следующий код должен быть простым, но преобразование из TypeB в int требует, чтобы компилятор автоматически выводил два преобразования типов. Но это не так.
Я не могу просто реализовать
оператор 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
}
С уважением
Так ты хочешь TypeB<T>
использовать определенные пользователем преобразования T
?
Создать шаблон operator U
который использует SFINAE для проверки операторов преобразования T
и принять, когда U
это тип T
имеет 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";
}
В любой неявной последовательности преобразования вам разрешено максимум один неявное пользовательское преобразование.
Ты можешь сказать int int_b = static_cast<TypeA>(b);
Тем не менее, чтобы уменьшить количество УДК до одного.