1

I have a class with a template constructor, and the code is actually calling the copy constructor, after the default-constructor, which does not make sense to me as the type is incorrect.

For example:

class A
{
  public:
    A(void); // default constructor
    A(const A& other); // copy constructor
    template<class TYPE>
    A(const TYPE& object_to_ref);  // template constructor
};

This template constructor works (is properly called in other cases), but is not properly recognized as the "correct" constructor from another template function:

template<class TYPE>
A& CreateA(const TYPE& object_to_ref)
{
  // THIS FUNCTION IS NEVER SPECIALIZED WITH "A", ONLY WITH "B" !!
  return *new A(object_to_ref);  // CALLS "A::A(const A&)" !!??
}

Example fail:

B my_b;
A& my_a = CreateA(my_b);  // "A::A(const A&)" called, not "A::A(const B&)"!

This does not make sense to me. The types are wrong to match the copy constructor. What happened? (MSVC2008)

My work-around is to not use the template constructor in this case:

template<class TYPE>
A& CreateA(const TYPE& object_to_ref)
{
  A* new_a = new A(); //DEFAULT CONSTRUCTOR
  new_a->setObjectToRef(object_to_ref); //OTHER TEMPLATE MEMBER FUNCTION
  return *new_a;
}

QUESTION: Why was the template constructor not called in this case?

(Work-around seems to behave properly, do you suggest an alternative?)

EDIT: B is unrelated, with no conversions specified between B and/or A:

class B
{
};
charley
  • 5,913
  • 1
  • 33
  • 58

1 Answers1

1

You didn't provide definition of B, so I'm going ahead assuming that A is B's ancestor and B can be implicitly cast to A. In this case your template for B is not being instantiated, because there is a perfectly suitable call already.

cababunga
  • 3,090
  • 15
  • 23
  • 1
    That doesn't make sense. You probably oversimplified your example. Is there any other implicit method of converting B to A? Like `operator A ()`? – cababunga Apr 02 '12 at 22:14
  • You were right: Didn't make sense, I oversimplified. There were more `template<>==>traits==>template<>` conversions going on, and one of them was unexpected-but-legitimate, ultimately causing the copy-constructor to be invoked in this case. My fault! (GOOD! IT WAS DRIVING ME CRAZY.) – charley Apr 03 '12 at 15:39