Reputation: 22143
I am testing out a way to mimic C# properties and created the following property
class:
struct BY_REF
{
template <class T>
struct TT_s
{
typedef T &TT_t;
};
};
struct BY_VAL
{
template <class T>
struct TT_s
{
typedef T TT_t;
};
};
template <class T, class P=BY_REF>
class property
{
private:
typedef typename P::template TT_s<T>::TT_t TT;
T &value;
property();
property(const property &);
property &operator=(const property &);
public:
explicit property(T &v) : value(v) {}
operator const TT() const
{
return value;
}
TT operator=(const TT i)
{
return value = i;
}
};
I tested this class with the following code:
int main()
{
int i;
std::string s;
property<int, BY_VAL> I(i);
property<std::string> S(s);
//stringproperty S(s);
I = 1337;
char c[] = "I am ";
S = std::string(c);
cout << /*S <<*/ I << endl;
return 0;
}
This gives me an unexpected compiler error, "no match for 'operator='
...", for the line S = std::string(c);
. I commented out the printing of S
because I the operator=
problem seems to be simpler, and I hope its solution will solve the operator<<
problem as well. To try to figure out what is going on, I instantiated the template manually as follows:
class stringproperty
{
private:
std::string &value;
stringproperty();
stringproperty(const stringproperty &);
stringproperty &operator=(const stringproperty &);
public:
explicit stringproperty(std::string &v) : value(v) {}
operator const std::string &() const
{
return value;
}
std::string &operator=(const std::string &i)
{
return value = i;
}
};
My manual version works. Can anyone explain why the template version doesn't? (I suspect it has something to do with the BY_REF
and BY_VAL
classes but then I do not know why it works for integers.)
Upvotes: 0
Views: 147
Reputation: 300129
Your manual version is erroneous, and the issue has nothing to do with templates.
typedef int& IntRef;
const int& == int const&
const IntRef == IntRef const == int& const
Notice the difference ? The issue is thus there: TT operator=(const TT i)
.
The general guideline is that if you want to treat a typedef
as a simple text replacement, then you need to start right now: Put the const
after the type it qualifies.
Upvotes: 4