9

Could someone please explain how to resolve the ambigious overload warning for make_unique, where the error comes from and what it does exactly mean (I do understand what an ambigious overload is but I am unsure why I get one for this particular code)? I am using c++11, therefore I use the recommended template from Herb Sutter.

Using it I get the following error:

Error   4   error C2668: 'make_unique' : ambiguous call to overloaded function

And the hover over tooltip in visual studio 13 gives me the following to methods:

function template "std::enable_if<!std::is_array<_Ty>::value, std::unique_ptr<_Ty,std::default_delete<_Ty>>>::type std::make_unique<_Ty,_Types...>(_Types &&..._Args)"
function template "std::unique_ptr<T, std::default_delete<T>> make_unique<T,Args...>(Args...)
argument types are: std::string

The second one should be the one called from the make_unique template

/* Will be part of c++14 and is just an oversight in c++11
 * From: http://herbsutter.com/gotw/_102/
 */
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args){
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

The constructor to be forwarded to:

Shader(const std::string& name);

The code generating the error

std::string _name = "Shader";
std::unique_ptr<Shader> s = make_unique<Shader>(_name); 
T.C.
  • 133,968
  • 17
  • 288
  • 421
Kevin Streicher
  • 484
  • 1
  • 8
  • 25

1 Answers1

5

The call is ambiguous because you do have std::make_unique, as shown by the tooltip contents you quote. And even though you did not write std::, since you are passing a std::string argument-dependent lookup kicks in to search that namespace automatically.

When you say "I am using C++11", that's not quite right, because Visual Studio doesn't let you choose which standard to write in. It just provides you with the latest support it has mustered for any given feature. And, apparently, Visual Studio 2013 has C++14's std::make_unique.

Remove yours.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Good catch. But the remaining question is why VS sees both as candidates. OP probably used `using namespace std;`? Which is another thing OP should fix. – Daniel Frey Feb 15 '15 at 07:57
  • That was my first guess and i have scanned all files for using namespace std; Sadly this is not the problem :( There is no using namespace for any namespace anymore, and I do not get why VS does see the C++14 method :) Am I missing something or is it possible it uses the std version altough there is no using namespace anymore? I am pretty sure the answer itself is correct but I wait for approval until someone finds or explains why the C++14 method is used. – Kevin Streicher Feb 15 '15 at 13:44
  • 1
    Ok, the answer definetly is correct as ::make_unique(_name) resolves it. There still remains the extra little question why VS does see the c++14 method without giving the namespace. Another question, if I simply use the c++14 methods, are there some things I need to be aware of beside that one obviously needs a c++14 capable compiler to build the project? – Kevin Streicher Feb 15 '15 at 13:51
  • Thinking about it even further I approved your answer because I could not find an argument to NOT use the c++14 version, could you think of one? – Kevin Streicher Feb 15 '15 at 15:10
  • @NoxMortem: No. You could keep your version of the function inside a preprocessor `#if` block (if you can figure out what macro to use for it) so that your code is ready to be ported to other compilers. But, otherwise, no. – Lightness Races in Orbit Feb 15 '15 at 15:36
  • @NoxMortem: As for why `std::make_unique` is found despite you not writing `std::`, that's due to argument-dependent lookup because your argument (an `std::string`) is in that namespace. It wouldn't have been found if you'd passed an `int` instead, say. – Lightness Races in Orbit Feb 15 '15 at 15:37
  • 2
    @LightnessRacesinOrbit It's ADL, I think the problem is that the compiler doesn't know `make_unique` is a *template-name* when you don't have the global scope version, so it can't parse the `<`. http://coliru.stacked-crooked.com/a/33fc5b4228e53f63 – T.C. Feb 15 '15 at 15:53