Hello,
this patch fixes the issue reported at
http://stackoverflow.com/q/20860535/1918193
that the error we get when implicitly constructing from an initializer
list using an explicit constructor doesn't have sfinae magic.
Bootstrap+testsuite on x86_64-unknown-linux-gnu.
2014-01-01 Marc Glisse <marc.gli...@inria.fr>
gcc/cp/
* call.c (convert_like_real): Check complain.
gcc/testsuite/
* g++.dg/cpp0x/initlist-explicit-sfinae.C: New file.
--
Marc Glisse
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c (revision 206274)
+++ gcc/cp/call.c (working copy)
@@ -5927,20 +5927,22 @@ convert_like_real (conversion *convs, tr
tree convfn = cand->fn;
unsigned i;
/* When converting from an init list we consider explicit
constructors, but actually trying to call one is an error. */
if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
/* Unless this is for direct-list-initialization. */
&& !(BRACE_ENCLOSED_INITIALIZER_P (expr)
&& CONSTRUCTOR_IS_DIRECT_INIT (expr)))
{
+ if (!(complain & tf_error))
+ return error_mark_node;
error ("converting to %qT from initializer list would use "
"explicit constructor %qD", totype, convfn);
}
/* If we're initializing from {}, it's value-initialization. */
if (BRACE_ENCLOSED_INITIALIZER_P (expr)
&& CONSTRUCTOR_NELTS (expr) == 0
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
{
bool direct = CONSTRUCTOR_IS_DIRECT_INIT (expr);
Index: gcc/testsuite/g++.dg/cpp0x/initlist-explicit-sfinae.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/initlist-explicit-sfinae.C (revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/initlist-explicit-sfinae.C (working copy)
@@ -0,0 +1,47 @@
+// { dg-do compile }
+// { dg-options -std=c++11 }
+template<typename _Tp>
+_Tp&& declval() noexcept;
+
+template<bool b>
+struct bt {
+ static constexpr bool value = b;
+};
+
+template <typename To_, typename... From_>
+class my_is_convertible_many {
+ private:
+ template <typename To>
+ struct indirector {
+ indirector(To);
+ };
+
+ template <typename To, typename... From>
+ struct tag {};
+
+ template <typename To, typename... From>
+ static auto test(tag<To, From...>)
+ -> decltype(indirector<To>({declval<From>()...}), bt<true>());
+ static auto test(...)
+ -> bt<false>;
+
+ public:
+ static constexpr bool value = decltype(test(tag<To_, From_...>()))::value;
+};
+
+struct A {};
+struct B {};
+struct C {};
+
+struct Test {
+ Test(A, A);
+ //Test(B, B);
+ explicit Test(C, C);
+};
+
+int main() {
+ static_assert(my_is_convertible_many<Test, A, A>::value,""); // true, correct
+ static_assert(!my_is_convertible_many<Test, B, B>::value,""); // false,
correct
+ static_assert(!my_is_convertible_many<Test, C, C>::value,""); // error
+ return 0;
+}
Property changes on: gcc/testsuite/g++.dg/cpp0x/initlist-explicit-sfinae.C
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision URL
\ No newline at end of property