enable_if и оператор преобразования?
-
28-09-2019 - |
Вопрос
Любой шанс использовать enable_if
С оператором преобразования типа? Кажется, сложно, поскольку оба возврата и списка параметров неявны.
Решение
Dixit The документация:
Кажется, не так, кажется, указать активатор для оператора преобразования. Преобразование конструкторов, однако, может иметь активаторы в качестве дополнительных аргументов по умолчанию.
Другие советы
Из маленьких исследований я сделал (и игнорируя комментарий C ++ 0x от johannes), мой ответ - это то, что это зависит от того, что вы хотите enable_if
за. Если вы хотите операцию преобразования в T
существовать или нет из типа T
Тогда кажется, что ответ нет, в C ++ 03 нет (как сказал UGO). Но если вам нужен enable_if
изменить поведение оператора в зависимости от типа T
Тогда да, есть обходной путь, который должен вызвать функцию поддержки помощника (называемой to<T>
Как предложил Matthieu).
#include<iostream>
#include<boost/utility/enable_if.hpp>
#include<boost/type_traits/is_class.hpp>
struct B{
B(const B& other){}
B(){}
};
struct A{
template<class T>
T to(typename boost::enable_if_c<not boost::is_class<T>::value, void*>::type = 0){
std::clog << "converted to non class" << std::endl;
return T(0);
}
template<class T>
T to(typename boost::enable_if_c<boost::is_class<T>::value, void*>::type = 0){
std::clog << "conveted to class" << std::endl;
return T();
}
template<class T>
operator T(){
return to<T>();
}
};
int main(){
A a;
double d = (double)a; // output: "converted to non class"
B b = (B)(a); // output: "converted to class"
return 0;
}
Для записи я разочаровался этим в течение нескольких дней, пока я не понял, что хочу enable_if
Не для Sfinae, а для изменения поведения с компиляцией времени. Вы также можете обнаружить, что это настоящая причина для вашей необходимости enable_if
также. Просто предложение.
(Обратите внимание, что это ответ для ERA C ++ 98)
Хотя я могу понять интерес к теоретику к вопросу, я лично воздерживаюсь от использования операторов преобразования как можно больше.
Единственный, который я когда-либо использовал с консистенцией, является преобразование в псевдо-булеву (с использованием безопасного Bool IDIOM), для смарт-указателей или прокси, и, как отмечается, я использую трюк, чтобы фактически предотвратить полное логическое семантическое ...
Если я когда-либо хочу облегчить преобразования, я предпочитаю что-то по линии:
template <class T>
T to() const;
который не страдает от ограничений (в срок от подписи) оператора преобразования и требует явного вызова, только потому, что это немного яснее.
На самом деле, я нашел путь; Мы используем частный неиспользуемый класс, чтобы отметить преобразование, которое не должно существовать, и мы используем boost::mpl::if_
Чтобы выбрать, создавать ли преобразование в Noconversion или на нужный тип.
class A {
class NoConversion { };
template<class B> operator typename boost::mpl::if_<Cond, B, NoConversion>::type() const;
}