Friday, August 14, 2009

Baffled by templated operator=

Now this really took me by surprise and I just believed it after extensive debugging. Here's the punchline: A templated operator= is not used for assignments from the same data-type. That means when test has a templated operator=, this does not call it:

test a, b;
a = b;


On a second thought, this is actually comprehensible behaviour. The compiler generates a default operator= for assignments of it's own type that calls operator= for each member. This default operator is even generated when a templated operator exists. And because overloaded functions have stronger "binding" than template-functions, the implicitly created and therefore overloading operator= is called. Here's an example:

#include <iostream>

struct test
{
template<typename T>
test &operator=(const T &value)
{
std::cout << "template operator=()" << std::endl;
return *this;
}
};

int main()
{
test a, b;
b = 10;
a = b;
}

You might think that the output is
operator=()
operator=()

but it isn't. The output contains only one line, because the generated operator= does not create any output.


It is extremely important to know this rule and don't fall into it's trap like I did. In my case I had a pointer-member and simply assigning it resulted in a double-free in the dtor of the last destroyed copy of that object. Here's the correct way to circumvent this:

#include <iostream>

struct test
{
template<typename T>
test &operator=(const T &value)
{
std::cout << "template operator=()" << std::endl;
return *this;
}
test &operator=(const test &value)
{
return operator=<test>(value);
}
};

int main()
{
test a, b;
b = 10;
a = b;
}

1 comment:

  1. O yes! that types of templates i have use before, which does,t support the = to same data type.
    Shopping Cart

    ReplyDelete