7

I have a human class with ctor using universal reference

class Human {
 public:
  template<typename T>
  explicit Human(T&& rhs) {
    // do some initialization work
  }

  Human(const Human& rhs);  // the default ctor I don't care about
}

Now if I have a const Human object

const Human one_I_do_not_care; // then play with that
Human the_human_I_care(one_I_do_not_care)  // now create another one

Does the last line use the template ctor or the default ctor? My understanding is the "const" will disqualify the template ctor, am I correct?

Human the_human_I_care(one_I_do_not_care)  // line in question

By const disqualify the template ctor, I mean adding const then it would not match the template ctor, not it still matches two but compiler picks one.

JFMR
  • 23,265
  • 4
  • 52
  • 76
WhatABeautifulWorld
  • 3,198
  • 3
  • 22
  • 30

1 Answers1

8

Does the last line use the template ctor or the default ctor? My understanding is the const will disqualify the template ctor, am I correct?

No. You are passing a const-qualified Human as an argument. Since both constructors would match equally well (i.e.: if the template would be instantiated to take a const Human&), then the non-template constructor is preferred over the template (and no template instantiation for a const Human& parameter ever occur).

JFMR
  • 23,265
  • 4
  • 52
  • 76
  • 1
    I did try to test it out. I think what you said is half correct: 1) Adding a const does pick the default ctor; 2) marking the default ctor *delete* makes it not be able to find a ctor, which means it's wrong to say "the template would be instantiated to take a const Human&". – WhatABeautifulWorld Jan 20 '18 at 18:05
  • 1
    @WhatABeautifulWorld by *would be instantiated* I mean it is **not** instantiated: instantiation does not happen. – JFMR Jan 20 '18 at 18:08
  • @水飲み鳥 "both constructors match equally well " this is not correct. The template ctor will not match after adding const. Please revise your answer and I will upvote :) – WhatABeautifulWorld Jan 20 '18 at 18:09
  • @WhatABeautifulWorld It should be "both ctors **would** match equally well* – JFMR Jan 20 '18 at 18:12
  • @水飲み鳥 I tested on my local machine, it seems if I mark the default ctor *delete*, the compiler could not find a ctor. If both match equally well, it would find the template ctor, right? That's all the question is about and the part I want to know. – WhatABeautifulWorld Jan 20 '18 at 18:15
  • 1
    @WhatABeautifulWorld if you delete the default ctor and you've not defined a non-template ctor, then you have no ctor at all. – JFMR Jan 20 '18 at 18:16
  • But I have the template ctor? I am confused? – WhatABeautifulWorld Jan 20 '18 at 18:17
  • 3
    @WhatABeautifulWorld, no, deleted constructors still participate in overload resolution. – Mário Feroldi Jan 20 '18 at 18:19
  • 3
    @WhatABeautifulWorld Deleting things aren't missing. They follow usual overload resolution rules. If they are selected, an error occurs. This is *different* than them not being there. – Yakk - Adam Nevraumont Jan 20 '18 at 18:20
  • @WhatABeautifulWorld the way to get the template "ctor" called is by kind of "playing" with the process overloading resolution: you must have at least one non-template ctor, so that it matches worse than the template ctor. That way the template ctor is elected. – JFMR Jan 20 '18 at 18:23
  • Thanks all! To summaries, T&& could still bind to const, const doesn't disqualify that. Seems hard to digest because of this: https://stackoverflow.com/questions/34556808/const-applied-to-universal-reference-parameter – WhatABeautifulWorld Jan 20 '18 at 18:23
  • Oh, @水飲み鳥 btw, your answer should be "No". My question is: does the const DISQUALIFY the template ctor or not. From the discussion above, it doesn't disqualify that. – WhatABeautifulWorld Jan 20 '18 at 18:28