I have the 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 it on godbolt.
If I compile it with clang (3.8.0):
clang++ oload.cpp -std=c++1y
everything runs fine.
If i compile it with gcc (6.1.1 20160602)
g++ oload.cpp -std=c++1y
I get:
oload.cpp: In function ‘int main()’: oload.cpp:30:29: error: call of overloaded ‘value(<brace-enclosed initializer list>)’ is 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 that difference?
Is the behavior of gcc correct?
EDIT: As slavanap pointed out in his answer, the error can be circumvented by removing the curly braces on call-site. Non the less I would like to know why the compilers behave differently.