I've cut down some C++ 11 code that was failing to compile on Visual Studio 2015 to the following which I think should compile (and does with clang and gcc):
#include <utility>
void test(const char* x);
int main()
{
const char x[] = "Hello world!";
test(std::forward<const char*>(x));
}
I understand the call to forward
isn't necessary here. This is cut down from a much more complex bit of code that decays any arrays in a variadic argument down to pointers and forwards everything on. I'm sure can find ways to work around this with template specialization or SFINAE, but I'd like to know whether it's valid C++ before I go down that road. The compiler is Visual Studio 2015, and the problem can be recreated on this online MSVC compiler. The compile error is:
main.cpp(13): error C2665: 'std::forward': none of the 2 overloads could convert all the argument types
c:\tools_root\cl\inc\type_traits(1238): note: could be '_Ty &&std::forward<const char*>(const char *&&) noexcept'
with
[
_Ty=const char *
]
c:\tools_root\cl\inc\type_traits(1231): note: or '_Ty &&std::forward<const char*>(const char *&) noexcept'
with
[
_Ty=const char *
]
main.cpp(13): note: while trying to match the argument list '(const char [13])'
Update:
@Yakk has suggested an example more like this:
void test(const char*&& x);
int main()
{
const char x[] = "Hello world!";
test(x);
}
Which gives a more informative error:
main.cpp(7): error C2664: 'void test(const char *&&)': cannot convert argument 1 from 'const char [13]' to 'const char *&&'
main.cpp(7): note: You cannot bind an lvalue to an rvalue reference
Again, this compiles on gcc and clang. The compiler flags for Visual C++ were /EHsc /nologo /W4 /c
. @Crazy Eddie suggests this might be down to a VC++ extension to pass temporaries as non const references.