Todd H
Todd H

Reputation: 75

Universal Reference and constness

This C++ code doesn't compile, you get an error "candidate function template not viable: 1st argument ('const int32_t' (aka 'const int')) would lose const qualifier"

I know I can solve this by adding an overload for Func(const T& value), but I'm curious to learn why this doesn't compile?

template <typename T> 
void Func(T&& value)
{
  // Do stuff
}

struct Obj
{
  int32_t Id{};
};

int main(int argc, char* argv[])
{
  const Obj i{};
  Func<int32_t>(i.Id);
}

Upvotes: 0

Views: 227

Answers (1)

cigien
cigien

Reputation: 60238

When you make this call:

Func<int32_t>(i.Id);

you are specifying the template arguments. This means the T&& in Func is not considered a forwarding reference at all. Instead, it's just an rvalue-reference, which is int32_t&&. As the compiler says, binding int32_t && to a int32_t const & would discard the const qualifier, and the call doesn't compile.

On the other hand, if you don't specify the template argument:

Func(i.Id);

then the T&& is indeed a forwarding reference, which deduces int32_t const &, and the call compiles.

Upvotes: 1

Related Questions