Ho tagliato giù qualche codice C++ 11 che è stato non riesce a compilare su Visual Studio 2015 per il seguito della quale credo dovrebbe compilare (e lo fa con clangore e gcc):Visual C++: trasmettere un array come un puntatore
#include <utility>
void test(const char* x);
int main()
{
const char x[] = "Hello world!";
test(std::forward<const char*>(x));
}
Capisco che la chiamata a forward
non è necessaria qui. Questo è ridotto da un bit di codice molto più complesso che decompone qualsiasi array in un argomento variadico fino a puntatori e inoltra tutto avanti. Sono sicuro che posso trovare dei modi per aggirare questo problema con la specializzazione dei modelli o SFINAE, ma mi piacerebbe sapere se è C++ valido prima di percorrere questa strada. Il compilatore è Visual Studio 2015 e il problema può essere ricreato on this online MSVC compiler. L'errore di compilazione è:
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])'
Aggiornamento:
@Yakk ha suggerito un esempio più simile a questo:
void test(const char*&& x);
int main()
{
const char x[] = "Hello world!";
test(x);
}
che dà un errore più informativo:
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
Anche in questo caso , questo compila su gcc e clang. I flag del compilatore per Visual C++ erano /EHsc /nologo /W4 /c
. @Crazy Eddie suggerisce che questo potrebbe essere dovuto ad un'estensione VC++ per passare i temporaries come riferimenti non const.
Mi aspetto che non corrisponda alla seconda versione perché il puntatore è in realtà un temporaneo. –
Il compilatore è in modalità C++ rigorosa o ha * eventuali * estensioni abilitate? – Yakk
Un esempio più semplice che mostra la differenza potrebbe essere 'void test (const char * &&) {} const char bob [] =" ciao "; prova (bob); '? – Yakk