Reputation: 33607
I'm attempting to do a templated explicit cast operator. I found that notationally, you actually can put an expression with type traits and std::enable_if
in the operator's "name" slot. But the following test doesn't give the desired behavior:
#include <iostream>
#include <type_traits>
class WillCast {
public:
explicit operator int () {
return 1020;
}
};
class WontCast {
public:
template <typename T>
typename std::enable_if<
std::is_same<T, int>::value, int
>::type toInteger()
{
return 1324;
}
template <typename T>
explicit operator typename std::enable_if<
std::is_same<T, int>::value, int
>::type ()
{
return 304;
}
};
int main() {
std::cout << static_cast<int>(WillCast{}) << "\n"; // ok
std::cout << WontCast{}.toInteger<int>() << "\n"; // ok
/* std::cout << static_cast<int>(WontCast{}); */ // error
};
The error coming back from gcc 4.8.2 is:
test.cpp: In function ‘int main()’:
test.cpp:27:45: error: invalid static_cast from type ‘WontCast’ to type ‘int’
std::cout << static_cast<int>(WontCast{});
If what I'm trying to do were not possible, I wouldn't be surprised. But it seems to think the syntax is all right, it's just not seeming to behave consistently between the "nearby" behaviors seen by WontCast::toInteger()
and WillCast::operator int()
.
(This is a reduced example, of course my desired enable_if
is trickier.)
UPDATE - "Sidebar intelligence(tm)" has thrown up How can I use std::enable_if in a conversion operator? which I didn't find through "BeforeYouAsked intelligence(tm)". I will look and see if it helps. Well, the solution used there doesn't seem to apply, because WontCast isn't a templated class. So not helping here.
Upvotes: 2
Views: 700
Reputation: 303156
If you move the enable_if
part into the template, this works:
template <typename T,
typename = typename std::enable_if<std::is_same<T, int>::value>::type
>
explicit operator T()
{
return 304;
}
Given that:
int i = static_cast<int>(WontCast{}); // ok
double d = static_cast<double>(WontCast{}); // invalid static_cast
Upvotes: 4