Reputation: 25
I'd like to make a template overload of operator |
for an enum
inside a class template.
Here is a minimal example:
#include <iostream>
using namespace std;
template <class T>
struct test1 {
enum test2 {
test3, test4
};
};
template <class T>
typename test1<T>::test2 operator | (typename test1<T>::test2 f1, typename test1<T>::test2 f2) {
return static_cast<typename test1<T>::test2>(
static_cast<unsigned>(f1) | static_cast<unsigned>(f2)
);
}
int main() {
test1<int>::test2 flags = test1<int>::test3 | test1<int>::test4; // error here
}
Compiler shows the following diagnostic in this code:
In function 'int main()':
error: invalid conversion from 'int' to 'test1<int>::test2' [-fpermissive]
test1<int>::test2 flags = test1<int>::test3 | test1<int>::test4;
I also tried compiling this code with LLVM 6.1.0.
What is the problem with this code?
Upvotes: 0
Views: 339
Reputation: 14714
The problem is that in typename test1<T>::test2
, template parameter T
is in a non-deduced context, so C++ can not deduce its template argument from the types of the function arguments.
You can see this by explicitly instantiating the function template:
test1<int>::test2 flags = operator | <int> (test1<int>::test3, test1<int>::test4);
Or by using a non-template friend function of the class template:
template <class T>
struct test1 {
enum test2 {
test3, test4
};
friend test2 operator | (test2 f1, test2 f2) {
return static_cast<test2>(
static_cast<unsigned>(f1) | static_cast<unsigned>(f2)
);
}
};
int main() {
test1<int>::test2 flags = test1<int>::test3 | test1<int>::test4;
}
See also:
Upvotes: 2