Reputation: 1077
I am reading the book Advanced C++ Metaprogramming and I encounter that a snippet of code at section 2.2.3. (page 49th) doesn't compile (My current compiler is Visual Studio 2013). The error arises at assignment but the book says that the assignment "ok: it ends up calling basic_inner::operator=". Did I miss something?
template <typename X, typename T>
struct basic_inner
{
template <typename T2>
basic_inner& operator=(const basic_inner<X, T2>&)
{
// do something...
return *this;
}
};
template <typename T>
struct outer
{
template <typename X>
struct inner : public basic_inner<X, T>
{
inner& operator=(const basic_inner<X, T> &that)
{
static_cast<basic_inner<X, T>&>(*this) = that;
return *this;
}
};
};
template <>
struct outer<int>
{
template <typename X>
struct inner : public basic_inner<X, int>
{
inner& operator=(const basic_inner<X, int> &that)
{
static_cast<basic_inner<X, int>&>(*this) = that;
return *this;
}
};
};
The client code is:
outer<double>::inner<void> x1;
outer<int>::inner<void> x2;
x1 = x2; // <-- error: no operator found which takes right-hand operand of type 'outer<int>::inner<void>'(or there is no acceptable conversion)
Upvotes: 0
Views: 155
Reputation: 2279
I guess that assignment operator of basic_inner
class is not visible in your derived class inner
, due to name hiding. You can put using basic_inner<X, T>::operator=;
to your outer
class and get something like this.
template <typename T>
struct outer {
template <typename X>
struct inner : public basic_inner<X, T> {
using basic_inner<X, T>::operator=;
inner& operator=(const basic_inner<X, T>& that) {
static_cast<basic_inner<X, T>&>(*this) = that;
return *this;
}
};
};
template <>
struct outer<int> {
template <typename X>
struct inner : public basic_inner<X, int> {
using basic_inner<X, int>::operator=;
inner& operator=(const basic_inner<X, int>& that) {
static_cast<basic_inner<X, int>&>(*this) = that;
return *this;
}
};
};
Upvotes: 1