Any chance to use enable_if
with a type conversion operator? Seems tricky, since both return type and parameters list are implicit.

- 2,255
- 2
- 21
- 32
-
7C++0x makes it possible by default arguments: `template
::type> operator T() { ... }` – Johannes Schaub - litb Jun 19 '10 at 22:06
4 Answers
From the little research I did (and ignoring the c++0x comment from Johannes), my answer is that it depends what you want the enable_if
for. If you want the conversion operation to T
to exist or not from the type T
then it seems that the answer is no, there is no way in C++03 (as Ugo said). But if you need the enable_if
to change the behavior of the operator depending on the type of T
then yes, there is a workaround which is to call an enabled helper function (called to<T>
as Matthieu suggested).
#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;
}
For the record, I was frustrated with this for several days, until I realized that I wanted enable_if
not for SFINAE but for compile-time behavior change. You may also find that this is the real reason for your need for enable_if
also. Just a suggestion.
(Please note that this is an answer for the C++98 era)

- 14,261
- 4
- 67
- 118
-
You say it is not possible that the operation "exists or not" depending on type T. However, if you leave one `to()` out, the corresponding cast will fail with a compile time error, which is the desired behavior. Am I missing something? – hannes Jul 09 '12 at 11:54
-
yes, I think you are right, but is that the intention behind the question? – alfC Jul 12 '12 at 06:13
-
Maybe I misunderstood your answer, you say "it is not possible in c++03", but then you show how it *is* possible. – hannes Jul 12 '12 at 17:15
Actually, I have found a way; we use a private, unused class to mark a conversion that shouldn't exist, and we use boost::mpl::if_
to select whether to produce a conversion to NoConversion, or to the desired type.
class A {
class NoConversion { };
template<class B> operator typename boost::mpl::if_<Cond, B, NoConversion>::type() const;
}

- 216
- 3
- 3
dixit the documentation:
There does not seem to be a way to specify an enabler for a conversion operator. Converting constructors, however, can have enablers as extra default arguments.

- 10,489
- 4
- 28
- 62
-
3With C++11 this is no longer the case. See http://stackoverflow.com/questions/18100297/how-can-i-use-stdenable-if-in-a-conversion-operator – Asher Nov 04 '15 at 07:10
While I can understand the theoritecal interest in the question, I personally refrain from using conversion operators as much as possible.
The only one I ever use with consistence is the conversion to a pseudo-boolean (using the Safe Bool idiom), for smart-pointers or proxies, and as noted I use a trick to actually prevent the full boolean semantic...
If I ever want to facilitate conversions, I much prefer something along the line of:
template <class T>
T to() const;
which does not suffer from the limitations (in term of signature) of the conversion operator and requires explicit invocation, just because it's a bit clearer.

- 287,565
- 48
- 449
- 722