Matt
Matt

Reputation: 22143

Trouble with C++ templates (big surprise!). Why won't this work?

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

Answers (1)

Matthieu M.
Matthieu M.

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

Related Questions