2 Replies Latest reply on Jan 15, 2018 11:41 PM by koval

    Studio 12.6 problem with partial specialization on function pointers with variadics

    koval

      Studio 12.6 C++ compiler fails on partial specializations like this:

      template<typename, typename>

      struct compatible_signature: std::false_type {};

       

      template<typename C1, typename C2, typename R, typename... A>

      struct compatible_signature<R(C1::*)(A...), R(C2::*)(A...)>: std::true_type {};

       

      struct X;

       

      static_assert(!compatible_signature<void(X::*)(), int(X::*)()>::value, "different return");

      static_assert(!compatible_signature<void(X::*)(int), void(X::*)(short)>::value, "different type");

      static_assert(!compatible_signature<void(X::*)(int, int), void(X::*)()>::value, "different arity");

      static_assert(!compatible_signature<void(X::*)(int), void(X::*)(int, int)>::value, "different arity");

      static_assert(!compatible_signature<void(X::*)(int, int, int), void(X::*)(int, int)>::value, "different arity");

       

      This looks like matching on prefix instead of full variadic pack. Seems that the problem is limited to function pointers, specialization on template-templates like Spec<X<A...>, Y<A...>> work fine

        • 1. Re: Studio 12.6 problem with partial specialization on function pointers with variadics
          Maxim Kartashev-Oracle

          Right, there's a bug in the routine that verifies that the pack has been deduced to identical values both times. There's no good workaround I could think of, unfortunately. If you change either of the first parameter's types to, say, char, that'll fool the compiler into working correctly, though.

           

          I filed bug 27390346. If you have a support contract, you can escalate for a patch.

           

          Thanks!

          1 person found this helpful
          • 2. Re: Studio 12.6 problem with partial specialization on function pointers with variadics
            koval

            Actually I came up with a simple solution which is to wrap parameter pack with a variadic template and match on template-templates which works fine:

            template<typename, typename>

            struct same_tuples: std::false_type {};

             

            template<template<typename...> class X, typename... A>

            struct same_tuples<X<A...>, X<A...>>: std::true_type {};

             

            template<typename...>

            struct wrapper {};

             

            template<typename C1, typename C2, typename R, typename... A1, typename... A2>

            struct compatible_signature<R(C1::*)(A1...), R(C2::*)(A2...)>: same_tuples<wrap<A1...>, wrap<A2...>>::type {};

             

            Main metafunction (compatible_signature) checks itself for return types and parameters match is delegated to a construct that CC can handle correctly

             

            Anyway thanks for submitting a bug, hopefully future releases of CC will be able to build clang without modifying the code