c++ - Gcc fails with "call of overload is ambignuous" while clang does not -


i have following code:

#include <experimental/string_view>  struct b_symbol {     template <typename t>      explicit b_symbol(t&& symbol)         : symbol(std::forward<t>(symbol)) {     }      std::experimental::string_view symbol; };  struct b_utf8 {     template <typename t>     explicit b_utf8(t&& value)         : value(std::forward<t>(value)) {     }      std::experimental::string_view value;  };  struct value {     explicit value(b_utf8) {}     explicit value(b_symbol) {}  };  int main() {     value v({b_utf8("test")}); } 

you can try on godbolt.

if compile clang (3.8.0):
clang++ oload.cpp -std=c++1y
runs fine.

if compile gcc (6.1.1 20160602)
g++ oload.cpp -std=c++1y
get:

oload.cpp: in function ‘int main()’: oload.cpp:30:29: error: call of overloaded ‘value(<brace-enclosed initializer list>)’ ambiguous      value v({b_utf8("test")});                              ^ oload.cpp:25:14: note: candidate: value::value(b_symbol)      explicit value(b_symbol) {}               ^~~~~ oload.cpp:24:14: note: candidate: value::value(b_utf8)      explicit value(b_utf8) {}               ^~~~~ oload.cpp:23:8: note: candidate: constexpr value::value(const value&)  struct value {         ^~~~~ oload.cpp:23:8: note: candidate: constexpr value::value(value&&) 

why difference?
behavior of gcc correct?

edit: slavanap pointed out in answer, error can circumvented removing curly braces on call-site. non less know why compilers behave differently.

you passing initialiser list constructor explicitly takes either b_utf8 or b_symbol, neither correct.

you must define constructor takes initialiser list if don't want use implicit casts.

i think in process of being changed c++17 , allowed clang way then.

edit: interestingly

struct  b_utf8 {    b_utf8() = default;   //b_utf8(){} };  struct value {   explicit value(b_utf8) {} };  int main() {     value v({b_utf8()}); } 

compiles but

struct  b_utf8 {    //b_utf8() = default;   b_utf8(){} };  struct value {   explicit value(b_utf8) {} };  int main() {     value v({b_utf8()}); } 

fails overload resolution. i'm not sure why, far can tell overload resolution should behave same in 2 cases.


Comments

Popular posts from this blog

Spring Boot + JPA + Hibernate: Unable to locate persister -

go - Golang: panic: runtime error: invalid memory address or nil pointer dereference using bufio.Scanner -

c - double free or corruption (fasttop) -