Yes, it is a constness issue.
mbozzi wrote: |
---|
You've attempted to make a non-const reference to a const int. This would violate const-correctness.
The non-const reference in your case is the unnamed formal parameter to foo, and the const int is the expression std::forward<const int>(j). |
Consider the function call
foo(std::forward<int>(j));
The function
foo's first parameter is a reference to
int, and the argument
std::forward<int>(j) has the matching type
int. Not a problem; the parameter to
foo is initialized somewhat like this:
1 2
|
int&& first_argument_to_foo = std::forward<int>(j);
int&& first_formal_parameter_to_foo = first_argument_to_foo // okay
|
Now consider the incorrect function call
foo(std::forward<const int>(j));
In this case,
foo's first parameter is (still) a reference to
int. But this time the argument
std::forward<int>(j) has the type
int const. This doesn't work: the parameter to
foo would be initialized like so
1 2
|
int const&& first_argument_to_foo = std::forward<int const>(j);
int&& first_formal_parameter_to_foo = first_argument_to_foo // wrong
|
Which is illegal, because the
first_argument_to_foo is a reference to
const. The compiler can add but not throw away that
const.
It is wrong for the same reason that this is wrong:
1 2 3 4 5 6
|
int f(int&) {};
int main()
{
int const x = 42;
f(x);
}
|
Or that this is wrong:
1 2
|
int const y = 42;
int& x = y;
|
In this case the calls to
std::forward are a red herring. Here
std::forward is equivalent to
std::move.