Reputation: 1861
I'm trying to implement an operator overload for a class such as:
template<class T> class A{
public:
T val;
A<T>& operator=(const T& v) {
this->val = v;
return *this;
}
}
So I can do:
A<bool> obj;
obj = true; // instead of obj.val = true
obj = false;
This works fine.
However, if I do this:
A<bool> obj;
obj = 123123; // bool is not a number!
It still works! Can I somehow prevent that?
I tried marking the overload explicit
like this:
explicit A<T>& operator=(const T& v) { ... }
but I get an error:
error C2071: 'A<T>::operator =': illegal storage class
Is it even possible to do this?
Upvotes: 0
Views: 81
Reputation: 141618
As suggested in comments, make a delete
d template function that matches everything except the one type you want to allow:
template<class T> class A
{
public:
T val;
A & operator=(T const &v) {
val = v;
return *this;
}
template<class U>
A & operator=(U const &v) = delete;
};
int main()
{
A<bool> a;
a = true;
a = 1; // error: use of deleted function
}
If you are going to do this a lot, you can offload the heavy lifting to a helper class:
template<typename T>
struct exact
{
T const &t;
exact(T const &t): t(t) {}
template<typename U>
exact(U u) = delete;
};
template<class T> class A
{
public:
T val;
A &operator=(exact<T> v) {
val = v.t;
return *this;
}
};
Upvotes: 2