Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

compiler cares about copy constructor when it doesn't need one

Why compiler cares about copy constructor when it doesn't need one?

#include <iostream>

template<typename T>
void print(T);

class Foo {
    Foo(const Foo&);
public:
    Foo(){}

};

template<>
void print(const Foo& f) {
    std::cout << "Foo\n";
}


int main(){
    Foo foo;
    print(foo);
}

function print is overloaded to accept const Foo& but compiler produces the following compilation error:

main.cpp: In function ‘int main()’:
main.cpp:21:14: error: ‘Foo::Foo(const Foo&)’ is private within this context
   21 |     print(foo);
      |              ^
main.cpp:7:5: note: declared private here
    7 |     Foo(const Foo&);
      |     ^~~
main.cpp:4:12: note:   initializing argument 1 of ‘void print(T) [with T = Foo]’
    4 | void print(T);
      |            ^

Why is it so? Obviously we don't need copy constructor, since we passing foo by reference and we have overload of print for that.

like image 617
Jouni Avatar asked Sep 30 '19 16:09

Jouni


1 Answers

Your specialization is not used in overload resolution. Overload resolution only synthesizes a signature from the primary template. The specialization is only used when calling the function, and only if the signature matches that which the compiler synthesized by itself. Since the primary takes an argument by value, this is the signature that participates in overload resolution:

void print(Foo); // T = Foo

And it doesn't match the signature you provided in the specialization (T = Foo const&), so the specialization isn't called. In fact, the only way to call your specialization, as is, is to specify the template argument explicitly:

print<Foo const&>(foo);

The way to proceed is not to specialize, but to overload. You can accomplish that by simply removing the template<> introducer. The regular overload participates in overload resolution, and will be chosen over the template generated one.

like image 76
StoryTeller - Unslander Monica Avatar answered Sep 30 '22 08:09

StoryTeller - Unslander Monica