c++ type alias not working when testing specialization





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







2















Using C++, trying to implement: is_specialization_of



template<typename T, template<typename...> class Template>
struct is_specialization_of : std::false_type {};

template<template<typename...> class Template, typename... Tn>
struct is_specialization_of<Template<Tn...>, Template> : std::true_type {};

template<typename... Tn>
struct tstruct {};

template<typename... Tn>
using ustruct = tstruct<Tn...>;

int main( int argc, char **argv )
{
printf( "test u<int> against u, return %sn", is_specialization_of<ustruct<int>, ustruct>::value ? "true" : "false" );
printf( "test u<int> against t, return %sn", is_specialization_of<ustruct<int>, tstruct>::value ? "true" : "false" );
printf( "test t<int> against u return %sn", is_specialization_of<tstruct<int>, ustruct>::value ? "true" : "false" );
printf( "test t<int> against t, return %sn", is_specialization_of<tstruct<int>, tstruct>::value ? "true" : "false" );
getchar();
return 0;
}


Return:



test u<int> against u, return false
test u<int> against t, return true
test t<int> against u return false
test t<int> against t, return true


Looks like the type alias is not considered exactly as the original type



I am using Visual Studio Community 2017




Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26732.1 for x64




However when trying to compile the same code using gcc, it returns:



test u<int> against u, return true
test u<int> against t, return true
test t<int> against u return true
test t<int> against t, return true


Is there anything I can do for a workaround?










share|improve this question































    2















    Using C++, trying to implement: is_specialization_of



    template<typename T, template<typename...> class Template>
    struct is_specialization_of : std::false_type {};

    template<template<typename...> class Template, typename... Tn>
    struct is_specialization_of<Template<Tn...>, Template> : std::true_type {};

    template<typename... Tn>
    struct tstruct {};

    template<typename... Tn>
    using ustruct = tstruct<Tn...>;

    int main( int argc, char **argv )
    {
    printf( "test u<int> against u, return %sn", is_specialization_of<ustruct<int>, ustruct>::value ? "true" : "false" );
    printf( "test u<int> against t, return %sn", is_specialization_of<ustruct<int>, tstruct>::value ? "true" : "false" );
    printf( "test t<int> against u return %sn", is_specialization_of<tstruct<int>, ustruct>::value ? "true" : "false" );
    printf( "test t<int> against t, return %sn", is_specialization_of<tstruct<int>, tstruct>::value ? "true" : "false" );
    getchar();
    return 0;
    }


    Return:



    test u<int> against u, return false
    test u<int> against t, return true
    test t<int> against u return false
    test t<int> against t, return true


    Looks like the type alias is not considered exactly as the original type



    I am using Visual Studio Community 2017




    Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26732.1 for x64




    However when trying to compile the same code using gcc, it returns:



    test u<int> against u, return true
    test u<int> against t, return true
    test t<int> against u return true
    test t<int> against t, return true


    Is there anything I can do for a workaround?










    share|improve this question



























      2












      2








      2








      Using C++, trying to implement: is_specialization_of



      template<typename T, template<typename...> class Template>
      struct is_specialization_of : std::false_type {};

      template<template<typename...> class Template, typename... Tn>
      struct is_specialization_of<Template<Tn...>, Template> : std::true_type {};

      template<typename... Tn>
      struct tstruct {};

      template<typename... Tn>
      using ustruct = tstruct<Tn...>;

      int main( int argc, char **argv )
      {
      printf( "test u<int> against u, return %sn", is_specialization_of<ustruct<int>, ustruct>::value ? "true" : "false" );
      printf( "test u<int> against t, return %sn", is_specialization_of<ustruct<int>, tstruct>::value ? "true" : "false" );
      printf( "test t<int> against u return %sn", is_specialization_of<tstruct<int>, ustruct>::value ? "true" : "false" );
      printf( "test t<int> against t, return %sn", is_specialization_of<tstruct<int>, tstruct>::value ? "true" : "false" );
      getchar();
      return 0;
      }


      Return:



      test u<int> against u, return false
      test u<int> against t, return true
      test t<int> against u return false
      test t<int> against t, return true


      Looks like the type alias is not considered exactly as the original type



      I am using Visual Studio Community 2017




      Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26732.1 for x64




      However when trying to compile the same code using gcc, it returns:



      test u<int> against u, return true
      test u<int> against t, return true
      test t<int> against u return true
      test t<int> against t, return true


      Is there anything I can do for a workaround?










      share|improve this question
















      Using C++, trying to implement: is_specialization_of



      template<typename T, template<typename...> class Template>
      struct is_specialization_of : std::false_type {};

      template<template<typename...> class Template, typename... Tn>
      struct is_specialization_of<Template<Tn...>, Template> : std::true_type {};

      template<typename... Tn>
      struct tstruct {};

      template<typename... Tn>
      using ustruct = tstruct<Tn...>;

      int main( int argc, char **argv )
      {
      printf( "test u<int> against u, return %sn", is_specialization_of<ustruct<int>, ustruct>::value ? "true" : "false" );
      printf( "test u<int> against t, return %sn", is_specialization_of<ustruct<int>, tstruct>::value ? "true" : "false" );
      printf( "test t<int> against u return %sn", is_specialization_of<tstruct<int>, ustruct>::value ? "true" : "false" );
      printf( "test t<int> against t, return %sn", is_specialization_of<tstruct<int>, tstruct>::value ? "true" : "false" );
      getchar();
      return 0;
      }


      Return:



      test u<int> against u, return false
      test u<int> against t, return true
      test t<int> against u return false
      test t<int> against t, return true


      Looks like the type alias is not considered exactly as the original type



      I am using Visual Studio Community 2017




      Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26732.1 for x64




      However when trying to compile the same code using gcc, it returns:



      test u<int> against u, return true
      test u<int> against t, return true
      test t<int> against u return true
      test t<int> against t, return true


      Is there anything I can do for a workaround?







      c++ templates specialization type-alias






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 25 '18 at 11:31







      drvkize

















      asked Nov 25 '18 at 10:57









      drvkizedrvkize

      354




      354
























          1 Answer
          1






          active

          oldest

          votes


















          1















          Looks like the type alias is not considered exactly as the original type, or did I miss something?




          The alias specialization is exactly the type it stands for. But the alias tempalte is an entirely distinct template. The reason for your output is specified by [temp.alias]




          1 A template-declaration in which the declaration is an
          alias-declaration declares the identifier to be an alias template. An
          alias template is a name for a family of types. The name of the alias
          template is a template-name.



          2 When a template-id refers to the specialization of an alias
          template, it is equivalent to the associated type obtained by
          substitution of its template-arguments for the template-parameters in
          the type-id of the alias template.




          If we examine your test cases with the above two paragraphs in mind, we see that:




          1. "test u<int> against u" - ustruct<int> is equivalent to specifying tstruct<int> directly. And tstruct<int> is not a specialization of ustruct. The trait needs to evaluate to false.


          2. "test u<int> against t" - Here ustruct<int> is again equivalent to specifying tstruct<int> directly. And tstruct<int> is a specialization of tstruct. The trait should report true.


          3. "test t<int> against u" - tstruct<int> is not a specialization of ustruct, like we observed previously. The trait should report false.


          4. "test t<int> against t" - Should report true.



          All your tests, when run in MSVC, conform to what the C++ standard says they should do. GCC is not conforming here, it's a compiler bug.






          share|improve this answer


























          • Thanks for the quick reply. So if we follow the standard, the expected behavior should be: "u<int> equivalent to t<int>" BUT "u is NOT equivalent to t" or "u and t can not be compared if they are not complete types"

            – drvkize
            Nov 25 '18 at 12:02













          • @drvkize - ustruct and tstruct aren't types, they are templates. And you can compare them, they should not be the same in a conforming compiler. like Clang for instance coliru.stacked-crooked.com/a/03321a93d172a609 .

            – StoryTeller
            Nov 25 '18 at 12:20












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53466773%2fc-type-alias-not-working-when-testing-specialization%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1















          Looks like the type alias is not considered exactly as the original type, or did I miss something?




          The alias specialization is exactly the type it stands for. But the alias tempalte is an entirely distinct template. The reason for your output is specified by [temp.alias]




          1 A template-declaration in which the declaration is an
          alias-declaration declares the identifier to be an alias template. An
          alias template is a name for a family of types. The name of the alias
          template is a template-name.



          2 When a template-id refers to the specialization of an alias
          template, it is equivalent to the associated type obtained by
          substitution of its template-arguments for the template-parameters in
          the type-id of the alias template.




          If we examine your test cases with the above two paragraphs in mind, we see that:




          1. "test u<int> against u" - ustruct<int> is equivalent to specifying tstruct<int> directly. And tstruct<int> is not a specialization of ustruct. The trait needs to evaluate to false.


          2. "test u<int> against t" - Here ustruct<int> is again equivalent to specifying tstruct<int> directly. And tstruct<int> is a specialization of tstruct. The trait should report true.


          3. "test t<int> against u" - tstruct<int> is not a specialization of ustruct, like we observed previously. The trait should report false.


          4. "test t<int> against t" - Should report true.



          All your tests, when run in MSVC, conform to what the C++ standard says they should do. GCC is not conforming here, it's a compiler bug.






          share|improve this answer


























          • Thanks for the quick reply. So if we follow the standard, the expected behavior should be: "u<int> equivalent to t<int>" BUT "u is NOT equivalent to t" or "u and t can not be compared if they are not complete types"

            – drvkize
            Nov 25 '18 at 12:02













          • @drvkize - ustruct and tstruct aren't types, they are templates. And you can compare them, they should not be the same in a conforming compiler. like Clang for instance coliru.stacked-crooked.com/a/03321a93d172a609 .

            – StoryTeller
            Nov 25 '18 at 12:20
















          1















          Looks like the type alias is not considered exactly as the original type, or did I miss something?




          The alias specialization is exactly the type it stands for. But the alias tempalte is an entirely distinct template. The reason for your output is specified by [temp.alias]




          1 A template-declaration in which the declaration is an
          alias-declaration declares the identifier to be an alias template. An
          alias template is a name for a family of types. The name of the alias
          template is a template-name.



          2 When a template-id refers to the specialization of an alias
          template, it is equivalent to the associated type obtained by
          substitution of its template-arguments for the template-parameters in
          the type-id of the alias template.




          If we examine your test cases with the above two paragraphs in mind, we see that:




          1. "test u<int> against u" - ustruct<int> is equivalent to specifying tstruct<int> directly. And tstruct<int> is not a specialization of ustruct. The trait needs to evaluate to false.


          2. "test u<int> against t" - Here ustruct<int> is again equivalent to specifying tstruct<int> directly. And tstruct<int> is a specialization of tstruct. The trait should report true.


          3. "test t<int> against u" - tstruct<int> is not a specialization of ustruct, like we observed previously. The trait should report false.


          4. "test t<int> against t" - Should report true.



          All your tests, when run in MSVC, conform to what the C++ standard says they should do. GCC is not conforming here, it's a compiler bug.






          share|improve this answer


























          • Thanks for the quick reply. So if we follow the standard, the expected behavior should be: "u<int> equivalent to t<int>" BUT "u is NOT equivalent to t" or "u and t can not be compared if they are not complete types"

            – drvkize
            Nov 25 '18 at 12:02













          • @drvkize - ustruct and tstruct aren't types, they are templates. And you can compare them, they should not be the same in a conforming compiler. like Clang for instance coliru.stacked-crooked.com/a/03321a93d172a609 .

            – StoryTeller
            Nov 25 '18 at 12:20














          1












          1








          1








          Looks like the type alias is not considered exactly as the original type, or did I miss something?




          The alias specialization is exactly the type it stands for. But the alias tempalte is an entirely distinct template. The reason for your output is specified by [temp.alias]




          1 A template-declaration in which the declaration is an
          alias-declaration declares the identifier to be an alias template. An
          alias template is a name for a family of types. The name of the alias
          template is a template-name.



          2 When a template-id refers to the specialization of an alias
          template, it is equivalent to the associated type obtained by
          substitution of its template-arguments for the template-parameters in
          the type-id of the alias template.




          If we examine your test cases with the above two paragraphs in mind, we see that:




          1. "test u<int> against u" - ustruct<int> is equivalent to specifying tstruct<int> directly. And tstruct<int> is not a specialization of ustruct. The trait needs to evaluate to false.


          2. "test u<int> against t" - Here ustruct<int> is again equivalent to specifying tstruct<int> directly. And tstruct<int> is a specialization of tstruct. The trait should report true.


          3. "test t<int> against u" - tstruct<int> is not a specialization of ustruct, like we observed previously. The trait should report false.


          4. "test t<int> against t" - Should report true.



          All your tests, when run in MSVC, conform to what the C++ standard says they should do. GCC is not conforming here, it's a compiler bug.






          share|improve this answer
















          Looks like the type alias is not considered exactly as the original type, or did I miss something?




          The alias specialization is exactly the type it stands for. But the alias tempalte is an entirely distinct template. The reason for your output is specified by [temp.alias]




          1 A template-declaration in which the declaration is an
          alias-declaration declares the identifier to be an alias template. An
          alias template is a name for a family of types. The name of the alias
          template is a template-name.



          2 When a template-id refers to the specialization of an alias
          template, it is equivalent to the associated type obtained by
          substitution of its template-arguments for the template-parameters in
          the type-id of the alias template.




          If we examine your test cases with the above two paragraphs in mind, we see that:




          1. "test u<int> against u" - ustruct<int> is equivalent to specifying tstruct<int> directly. And tstruct<int> is not a specialization of ustruct. The trait needs to evaluate to false.


          2. "test u<int> against t" - Here ustruct<int> is again equivalent to specifying tstruct<int> directly. And tstruct<int> is a specialization of tstruct. The trait should report true.


          3. "test t<int> against u" - tstruct<int> is not a specialization of ustruct, like we observed previously. The trait should report false.


          4. "test t<int> against t" - Should report true.



          All your tests, when run in MSVC, conform to what the C++ standard says they should do. GCC is not conforming here, it's a compiler bug.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 25 '18 at 11:51

























          answered Nov 25 '18 at 11:22









          StoryTellerStoryTeller

          107k15224288




          107k15224288













          • Thanks for the quick reply. So if we follow the standard, the expected behavior should be: "u<int> equivalent to t<int>" BUT "u is NOT equivalent to t" or "u and t can not be compared if they are not complete types"

            – drvkize
            Nov 25 '18 at 12:02













          • @drvkize - ustruct and tstruct aren't types, they are templates. And you can compare them, they should not be the same in a conforming compiler. like Clang for instance coliru.stacked-crooked.com/a/03321a93d172a609 .

            – StoryTeller
            Nov 25 '18 at 12:20



















          • Thanks for the quick reply. So if we follow the standard, the expected behavior should be: "u<int> equivalent to t<int>" BUT "u is NOT equivalent to t" or "u and t can not be compared if they are not complete types"

            – drvkize
            Nov 25 '18 at 12:02













          • @drvkize - ustruct and tstruct aren't types, they are templates. And you can compare them, they should not be the same in a conforming compiler. like Clang for instance coliru.stacked-crooked.com/a/03321a93d172a609 .

            – StoryTeller
            Nov 25 '18 at 12:20

















          Thanks for the quick reply. So if we follow the standard, the expected behavior should be: "u<int> equivalent to t<int>" BUT "u is NOT equivalent to t" or "u and t can not be compared if they are not complete types"

          – drvkize
          Nov 25 '18 at 12:02







          Thanks for the quick reply. So if we follow the standard, the expected behavior should be: "u<int> equivalent to t<int>" BUT "u is NOT equivalent to t" or "u and t can not be compared if they are not complete types"

          – drvkize
          Nov 25 '18 at 12:02















          @drvkize - ustruct and tstruct aren't types, they are templates. And you can compare them, they should not be the same in a conforming compiler. like Clang for instance coliru.stacked-crooked.com/a/03321a93d172a609 .

          – StoryTeller
          Nov 25 '18 at 12:20





          @drvkize - ustruct and tstruct aren't types, they are templates. And you can compare them, they should not be the same in a conforming compiler. like Clang for instance coliru.stacked-crooked.com/a/03321a93d172a609 .

          – StoryTeller
          Nov 25 '18 at 12:20




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53466773%2fc-type-alias-not-working-when-testing-specialization%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Xamarin.form Move up view when keyboard appear

          Post-Redirect-Get with Spring WebFlux and Thymeleaf

          Anylogic : not able to use stopDelay()