Unexpected overload resolution in visual studio involving void *, string and const char []

I had an unexpected overload behavior using the Visual Studio compiler (tested in VS2010 and VS2012).

Minimal example:

#include <iostream>
#include <string>

void f(void *)
{
    std::cout << "f(void*)\n";
}

void f(const std::string &)
{
    std::cout << "f(const std::string &)\n";
}

int main()
{
    f("Hello World!");
}

Output:

> f(void *)

Expected Auptut:

> f(const std::string &)

Compiling with GCC (tested since 4.6.3) generates the expected result.

If I comment on the "const std :: string &" version f (), the visual studio happily compiles in / W 4 without any warning, and GCC emits the following error (as expected): "invalid conversion from" const void * " in "void *" [-fpermissive] ".

Does anyone know why the visual studio behaves this way, choosing mainly overloading const cast over conversion to std :: string for char []?

, , VS ?

+4
3

VS 2013 Microsoft const , Microsoft ++:

Microsoft

Visual ++ non-const char wchar_t. C, ++ 98 ++ 11.

...

, non_const, /Zc:strictStrings (Disable string literal type conversion).

, VS 2013 (, VS 2012), Microsoft ++, C char.

+6

, . char const[] std::string , ; void* . , " ", , .

, ++ type, std::string. char const* :

void f( void* );
void f( std::string const& );
inline void f( char const* p ) { f( std::string( p ) ); }

.

( : : std::string, char const* , , int, , , double, .)

+2

, , , MSVC const char*, void*.

, void* void const*, . "", void const*. , : "" - char const(&)[1] ( const char), std::string, char const(&)[1] , std::string. std::string , , gcc, const !

, std::string.

template<typename S, typename=typename std::enable_if<std::is_convertible<S,std::string>::value>::type>
void f(S&&s){
  f(std::string{std::forward<S>(s)});
}

( const ).

() :

void f(void const* v, std::false_type){
  std::cout << "f(void*)\n";
}
void f(std::string const& s, std::true_type){
  std::cout << "f(const std::string &)\n";
}
template<typename T>
void f(T&&t){
  return f(std::forward<T>(t), std::is_convertible<T,std::string>() );
}

both of them - methods of manual scheduling of overload, are shifted to the side std::string.

living example

Note that literals are std::stringnow possible in C ++, but I would advise against requiring them based on fragility.

+1
source

Source: https://habr.com/ru/post/1530200/


All Articles