Type deduction time

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












8















I ran into this problem earlier today. In the following code:



template <int> struct Holder ;

template <typename> struct Helper using T = Holder<__COUNTER__>; ; // ???

int main()
auto a = typename Helper<bool>::T();
auto b = typename Helper<int>::T();

std::cout << (typeid(a) == typeid(b)) << std::endl;
return 0;



When compiled and executed with:



g++ test.cpp -std=c++11 -o test
./test


It prints out 1 instead of 0, meaning that the 2 Ts in Helper<int> and Helper<bool> are the same type, which makes me wonder:



  1. Why the line marked with // ??? is executed only once instead of once for each of the type?

  2. Is there a way to force the line to be executed once for each of the type and preferably without modifying the definition of Holder?

====================================================
Clarifications:



The (closer to) real scenario is:



  1. The struct Holder is defined in a header from a third-party library. The type for the struct is actually very complicated and the library writer provides users with another macro:

template <bool, int> struct Holder ;

#define DEF_HOLDER(b) Holder<b, __COUNTER__>()


At some point of the program, I want to take a "snapshot" of the type with current counter by aliasing the type so that it could be used in a function:



template <bool b>
struct Helper using T = decltype(DEF_HOLDER(b)); ;

template <bool b, typename R = typename Helper<b>::T>
R Func()
return R();


// Note that the following does not work:
// Since the 2 types generated by DEF_HOLDER do not match.
template <bool b>
auto Func() -> decltype(DEF_HOLDER(b))
return DEF_HOLDER(b);



The problem here is that the following 2 usage has inconsistent semantics as illustrated:



int main() 
auto a = DEF_HOLDER(true);
auto b = DEF_HOLDER(true);
auto c = Func<true>();
auto d = Func<true>();

std::cout << (typeid(a) == typeid(b)) << std::endl; // prints 0
std::cout << (typeid(c) == typeid(d)) << std::endl; // prints 1

return 0;



In my use case, it is important for multiple invocation of Func to return different types as it does with invoking DEF_HOLDER directly.










share|improve this question



















  • 1





    Even though it prints 1 it does not mean that Helper<int> and Helper<bool> are the same type. They are different types static_assert(false == ::std::is_same_v<Helper<int>, Helper<bool>>);. It is not clear what are you trying to achieve here.

    – VTT
    Feb 6 at 7:40







  • 3





    @VTT - The OP is asking about Helper<bool>::T and Helper<int>::T - which are the same type here.

    – StoryTeller
    Feb 6 at 7:51






  • 1





    @StoryTeller Yes, but if OP wants to get two different types from the Helper<bool> and Helper<int> he can use these types themselves. Or make something like struct T; instead of using T = Holder<__COUNTER__>;. So it is not clear why would he need that Holder type.

    – VTT
    Feb 6 at 7:56












  • @VTT - I imagine this is some sort of simplified form of an attempt at meta-programming. I agree that this might be an XY problem though.

    – StoryTeller
    Feb 6 at 7:57











  • @kkspeed - Instead of fixating on question 2, which is what you feel is the solution to your actual problem, would you mind telling us a thing or two about your end goal? Like I said already, this has the feeling of an XY question about it.

    – StoryTeller
    Feb 6 at 8:00
















8















I ran into this problem earlier today. In the following code:



template <int> struct Holder ;

template <typename> struct Helper using T = Holder<__COUNTER__>; ; // ???

int main()
auto a = typename Helper<bool>::T();
auto b = typename Helper<int>::T();

std::cout << (typeid(a) == typeid(b)) << std::endl;
return 0;



When compiled and executed with:



g++ test.cpp -std=c++11 -o test
./test


It prints out 1 instead of 0, meaning that the 2 Ts in Helper<int> and Helper<bool> are the same type, which makes me wonder:



  1. Why the line marked with // ??? is executed only once instead of once for each of the type?

  2. Is there a way to force the line to be executed once for each of the type and preferably without modifying the definition of Holder?

====================================================
Clarifications:



The (closer to) real scenario is:



  1. The struct Holder is defined in a header from a third-party library. The type for the struct is actually very complicated and the library writer provides users with another macro:

template <bool, int> struct Holder ;

#define DEF_HOLDER(b) Holder<b, __COUNTER__>()


At some point of the program, I want to take a "snapshot" of the type with current counter by aliasing the type so that it could be used in a function:



template <bool b>
struct Helper using T = decltype(DEF_HOLDER(b)); ;

template <bool b, typename R = typename Helper<b>::T>
R Func()
return R();


// Note that the following does not work:
// Since the 2 types generated by DEF_HOLDER do not match.
template <bool b>
auto Func() -> decltype(DEF_HOLDER(b))
return DEF_HOLDER(b);



The problem here is that the following 2 usage has inconsistent semantics as illustrated:



int main() 
auto a = DEF_HOLDER(true);
auto b = DEF_HOLDER(true);
auto c = Func<true>();
auto d = Func<true>();

std::cout << (typeid(a) == typeid(b)) << std::endl; // prints 0
std::cout << (typeid(c) == typeid(d)) << std::endl; // prints 1

return 0;



In my use case, it is important for multiple invocation of Func to return different types as it does with invoking DEF_HOLDER directly.










share|improve this question



















  • 1





    Even though it prints 1 it does not mean that Helper<int> and Helper<bool> are the same type. They are different types static_assert(false == ::std::is_same_v<Helper<int>, Helper<bool>>);. It is not clear what are you trying to achieve here.

    – VTT
    Feb 6 at 7:40







  • 3





    @VTT - The OP is asking about Helper<bool>::T and Helper<int>::T - which are the same type here.

    – StoryTeller
    Feb 6 at 7:51






  • 1





    @StoryTeller Yes, but if OP wants to get two different types from the Helper<bool> and Helper<int> he can use these types themselves. Or make something like struct T; instead of using T = Holder<__COUNTER__>;. So it is not clear why would he need that Holder type.

    – VTT
    Feb 6 at 7:56












  • @VTT - I imagine this is some sort of simplified form of an attempt at meta-programming. I agree that this might be an XY problem though.

    – StoryTeller
    Feb 6 at 7:57











  • @kkspeed - Instead of fixating on question 2, which is what you feel is the solution to your actual problem, would you mind telling us a thing or two about your end goal? Like I said already, this has the feeling of an XY question about it.

    – StoryTeller
    Feb 6 at 8:00














8












8








8


1






I ran into this problem earlier today. In the following code:



template <int> struct Holder ;

template <typename> struct Helper using T = Holder<__COUNTER__>; ; // ???

int main()
auto a = typename Helper<bool>::T();
auto b = typename Helper<int>::T();

std::cout << (typeid(a) == typeid(b)) << std::endl;
return 0;



When compiled and executed with:



g++ test.cpp -std=c++11 -o test
./test


It prints out 1 instead of 0, meaning that the 2 Ts in Helper<int> and Helper<bool> are the same type, which makes me wonder:



  1. Why the line marked with // ??? is executed only once instead of once for each of the type?

  2. Is there a way to force the line to be executed once for each of the type and preferably without modifying the definition of Holder?

====================================================
Clarifications:



The (closer to) real scenario is:



  1. The struct Holder is defined in a header from a third-party library. The type for the struct is actually very complicated and the library writer provides users with another macro:

template <bool, int> struct Holder ;

#define DEF_HOLDER(b) Holder<b, __COUNTER__>()


At some point of the program, I want to take a "snapshot" of the type with current counter by aliasing the type so that it could be used in a function:



template <bool b>
struct Helper using T = decltype(DEF_HOLDER(b)); ;

template <bool b, typename R = typename Helper<b>::T>
R Func()
return R();


// Note that the following does not work:
// Since the 2 types generated by DEF_HOLDER do not match.
template <bool b>
auto Func() -> decltype(DEF_HOLDER(b))
return DEF_HOLDER(b);



The problem here is that the following 2 usage has inconsistent semantics as illustrated:



int main() 
auto a = DEF_HOLDER(true);
auto b = DEF_HOLDER(true);
auto c = Func<true>();
auto d = Func<true>();

std::cout << (typeid(a) == typeid(b)) << std::endl; // prints 0
std::cout << (typeid(c) == typeid(d)) << std::endl; // prints 1

return 0;



In my use case, it is important for multiple invocation of Func to return different types as it does with invoking DEF_HOLDER directly.










share|improve this question
















I ran into this problem earlier today. In the following code:



template <int> struct Holder ;

template <typename> struct Helper using T = Holder<__COUNTER__>; ; // ???

int main()
auto a = typename Helper<bool>::T();
auto b = typename Helper<int>::T();

std::cout << (typeid(a) == typeid(b)) << std::endl;
return 0;



When compiled and executed with:



g++ test.cpp -std=c++11 -o test
./test


It prints out 1 instead of 0, meaning that the 2 Ts in Helper<int> and Helper<bool> are the same type, which makes me wonder:



  1. Why the line marked with // ??? is executed only once instead of once for each of the type?

  2. Is there a way to force the line to be executed once for each of the type and preferably without modifying the definition of Holder?

====================================================
Clarifications:



The (closer to) real scenario is:



  1. The struct Holder is defined in a header from a third-party library. The type for the struct is actually very complicated and the library writer provides users with another macro:

template <bool, int> struct Holder ;

#define DEF_HOLDER(b) Holder<b, __COUNTER__>()


At some point of the program, I want to take a "snapshot" of the type with current counter by aliasing the type so that it could be used in a function:



template <bool b>
struct Helper using T = decltype(DEF_HOLDER(b)); ;

template <bool b, typename R = typename Helper<b>::T>
R Func()
return R();


// Note that the following does not work:
// Since the 2 types generated by DEF_HOLDER do not match.
template <bool b>
auto Func() -> decltype(DEF_HOLDER(b))
return DEF_HOLDER(b);



The problem here is that the following 2 usage has inconsistent semantics as illustrated:



int main() 
auto a = DEF_HOLDER(true);
auto b = DEF_HOLDER(true);
auto c = Func<true>();
auto d = Func<true>();

std::cout << (typeid(a) == typeid(b)) << std::endl; // prints 0
std::cout << (typeid(c) == typeid(d)) << std::endl; // prints 1

return 0;



In my use case, it is important for multiple invocation of Func to return different types as it does with invoking DEF_HOLDER directly.







c++ templates c-preprocessor






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 6 at 8:49







kkspeed

















asked Feb 6 at 7:23









kkspeedkkspeed

14317




14317







  • 1





    Even though it prints 1 it does not mean that Helper<int> and Helper<bool> are the same type. They are different types static_assert(false == ::std::is_same_v<Helper<int>, Helper<bool>>);. It is not clear what are you trying to achieve here.

    – VTT
    Feb 6 at 7:40







  • 3





    @VTT - The OP is asking about Helper<bool>::T and Helper<int>::T - which are the same type here.

    – StoryTeller
    Feb 6 at 7:51






  • 1





    @StoryTeller Yes, but if OP wants to get two different types from the Helper<bool> and Helper<int> he can use these types themselves. Or make something like struct T; instead of using T = Holder<__COUNTER__>;. So it is not clear why would he need that Holder type.

    – VTT
    Feb 6 at 7:56












  • @VTT - I imagine this is some sort of simplified form of an attempt at meta-programming. I agree that this might be an XY problem though.

    – StoryTeller
    Feb 6 at 7:57











  • @kkspeed - Instead of fixating on question 2, which is what you feel is the solution to your actual problem, would you mind telling us a thing or two about your end goal? Like I said already, this has the feeling of an XY question about it.

    – StoryTeller
    Feb 6 at 8:00













  • 1





    Even though it prints 1 it does not mean that Helper<int> and Helper<bool> are the same type. They are different types static_assert(false == ::std::is_same_v<Helper<int>, Helper<bool>>);. It is not clear what are you trying to achieve here.

    – VTT
    Feb 6 at 7:40







  • 3





    @VTT - The OP is asking about Helper<bool>::T and Helper<int>::T - which are the same type here.

    – StoryTeller
    Feb 6 at 7:51






  • 1





    @StoryTeller Yes, but if OP wants to get two different types from the Helper<bool> and Helper<int> he can use these types themselves. Or make something like struct T; instead of using T = Holder<__COUNTER__>;. So it is not clear why would he need that Holder type.

    – VTT
    Feb 6 at 7:56












  • @VTT - I imagine this is some sort of simplified form of an attempt at meta-programming. I agree that this might be an XY problem though.

    – StoryTeller
    Feb 6 at 7:57











  • @kkspeed - Instead of fixating on question 2, which is what you feel is the solution to your actual problem, would you mind telling us a thing or two about your end goal? Like I said already, this has the feeling of an XY question about it.

    – StoryTeller
    Feb 6 at 8:00








1




1





Even though it prints 1 it does not mean that Helper<int> and Helper<bool> are the same type. They are different types static_assert(false == ::std::is_same_v<Helper<int>, Helper<bool>>);. It is not clear what are you trying to achieve here.

– VTT
Feb 6 at 7:40






Even though it prints 1 it does not mean that Helper<int> and Helper<bool> are the same type. They are different types static_assert(false == ::std::is_same_v<Helper<int>, Helper<bool>>);. It is not clear what are you trying to achieve here.

– VTT
Feb 6 at 7:40





3




3





@VTT - The OP is asking about Helper<bool>::T and Helper<int>::T - which are the same type here.

– StoryTeller
Feb 6 at 7:51





@VTT - The OP is asking about Helper<bool>::T and Helper<int>::T - which are the same type here.

– StoryTeller
Feb 6 at 7:51




1




1





@StoryTeller Yes, but if OP wants to get two different types from the Helper<bool> and Helper<int> he can use these types themselves. Or make something like struct T; instead of using T = Holder<__COUNTER__>;. So it is not clear why would he need that Holder type.

– VTT
Feb 6 at 7:56






@StoryTeller Yes, but if OP wants to get two different types from the Helper<bool> and Helper<int> he can use these types themselves. Or make something like struct T; instead of using T = Holder<__COUNTER__>;. So it is not clear why would he need that Holder type.

– VTT
Feb 6 at 7:56














@VTT - I imagine this is some sort of simplified form of an attempt at meta-programming. I agree that this might be an XY problem though.

– StoryTeller
Feb 6 at 7:57





@VTT - I imagine this is some sort of simplified form of an attempt at meta-programming. I agree that this might be an XY problem though.

– StoryTeller
Feb 6 at 7:57













@kkspeed - Instead of fixating on question 2, which is what you feel is the solution to your actual problem, would you mind telling us a thing or two about your end goal? Like I said already, this has the feeling of an XY question about it.

– StoryTeller
Feb 6 at 8:00






@kkspeed - Instead of fixating on question 2, which is what you feel is the solution to your actual problem, would you mind telling us a thing or two about your end goal? Like I said already, this has the feeling of an XY question about it.

– StoryTeller
Feb 6 at 8:00













2 Answers
2






active

oldest

votes


















13














The symbol __COUNTER__ is a preprocessor macro, it's expanded once only.



That means T will always be Holder<0> (since __COUNTER__ starts at zero), no matter the type used for the template Helper.



See e.g. this GCC predefined macro reference for more information about __COUNTER__.






share|improve this answer

























  • Thanks. Please see my clarification. Is there a way to force multiple expansion in this case?

    – kkspeed
    Feb 6 at 8:51






  • 1





    @kkspeed: Only this way, which is fragile, not standard conforming, difficult to understand and fun ; ): b.atch.se/posts/non-constant-constant-expressions Here is a standard committee voice over this technique: open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118

    – Michał Łoś
    Feb 6 at 9:04



















0














I am not sure whether I completely understand the problem, but since C++14 there is no need to use DEF_HOLDER two times. The following code also works:



template <bool b>
auto Func()
return DEF_HOLDER(b);



If you want a different type for every function call, you can add the int parameter:



template <bool b, int i>
auto Func()

return Holder<b, i>();



You could hide this int in a macro:



#define FUNC(b) Func<b,__COUNTER__>();


Then a,b and c,d have the same semantics:



int main() 
auto a = DEF_HOLDER(true);
auto b = DEF_HOLDER(true);
auto c = FUNC(true);
auto d = FUNC(true);

std::cout << (typeid(a) == typeid(b)) << std::endl; // prints 0
std::cout << (typeid(c) == typeid(d)) << std::endl; // prints 0

return 0;






share|improve this answer
























    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%2f54548491%2ftype-deduction-time%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    13














    The symbol __COUNTER__ is a preprocessor macro, it's expanded once only.



    That means T will always be Holder<0> (since __COUNTER__ starts at zero), no matter the type used for the template Helper.



    See e.g. this GCC predefined macro reference for more information about __COUNTER__.






    share|improve this answer

























    • Thanks. Please see my clarification. Is there a way to force multiple expansion in this case?

      – kkspeed
      Feb 6 at 8:51






    • 1





      @kkspeed: Only this way, which is fragile, not standard conforming, difficult to understand and fun ; ): b.atch.se/posts/non-constant-constant-expressions Here is a standard committee voice over this technique: open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118

      – Michał Łoś
      Feb 6 at 9:04
















    13














    The symbol __COUNTER__ is a preprocessor macro, it's expanded once only.



    That means T will always be Holder<0> (since __COUNTER__ starts at zero), no matter the type used for the template Helper.



    See e.g. this GCC predefined macro reference for more information about __COUNTER__.






    share|improve this answer

























    • Thanks. Please see my clarification. Is there a way to force multiple expansion in this case?

      – kkspeed
      Feb 6 at 8:51






    • 1





      @kkspeed: Only this way, which is fragile, not standard conforming, difficult to understand and fun ; ): b.atch.se/posts/non-constant-constant-expressions Here is a standard committee voice over this technique: open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118

      – Michał Łoś
      Feb 6 at 9:04














    13












    13








    13







    The symbol __COUNTER__ is a preprocessor macro, it's expanded once only.



    That means T will always be Holder<0> (since __COUNTER__ starts at zero), no matter the type used for the template Helper.



    See e.g. this GCC predefined macro reference for more information about __COUNTER__.






    share|improve this answer















    The symbol __COUNTER__ is a preprocessor macro, it's expanded once only.



    That means T will always be Holder<0> (since __COUNTER__ starts at zero), no matter the type used for the template Helper.



    See e.g. this GCC predefined macro reference for more information about __COUNTER__.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Feb 6 at 7:34

























    answered Feb 6 at 7:25









    Some programmer dudeSome programmer dude

    301k25264424




    301k25264424












    • Thanks. Please see my clarification. Is there a way to force multiple expansion in this case?

      – kkspeed
      Feb 6 at 8:51






    • 1





      @kkspeed: Only this way, which is fragile, not standard conforming, difficult to understand and fun ; ): b.atch.se/posts/non-constant-constant-expressions Here is a standard committee voice over this technique: open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118

      – Michał Łoś
      Feb 6 at 9:04


















    • Thanks. Please see my clarification. Is there a way to force multiple expansion in this case?

      – kkspeed
      Feb 6 at 8:51






    • 1





      @kkspeed: Only this way, which is fragile, not standard conforming, difficult to understand and fun ; ): b.atch.se/posts/non-constant-constant-expressions Here is a standard committee voice over this technique: open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118

      – Michał Łoś
      Feb 6 at 9:04

















    Thanks. Please see my clarification. Is there a way to force multiple expansion in this case?

    – kkspeed
    Feb 6 at 8:51





    Thanks. Please see my clarification. Is there a way to force multiple expansion in this case?

    – kkspeed
    Feb 6 at 8:51




    1




    1





    @kkspeed: Only this way, which is fragile, not standard conforming, difficult to understand and fun ; ): b.atch.se/posts/non-constant-constant-expressions Here is a standard committee voice over this technique: open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118

    – Michał Łoś
    Feb 6 at 9:04






    @kkspeed: Only this way, which is fragile, not standard conforming, difficult to understand and fun ; ): b.atch.se/posts/non-constant-constant-expressions Here is a standard committee voice over this technique: open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118

    – Michał Łoś
    Feb 6 at 9:04














    0














    I am not sure whether I completely understand the problem, but since C++14 there is no need to use DEF_HOLDER two times. The following code also works:



    template <bool b>
    auto Func()
    return DEF_HOLDER(b);



    If you want a different type for every function call, you can add the int parameter:



    template <bool b, int i>
    auto Func()

    return Holder<b, i>();



    You could hide this int in a macro:



    #define FUNC(b) Func<b,__COUNTER__>();


    Then a,b and c,d have the same semantics:



    int main() 
    auto a = DEF_HOLDER(true);
    auto b = DEF_HOLDER(true);
    auto c = FUNC(true);
    auto d = FUNC(true);

    std::cout << (typeid(a) == typeid(b)) << std::endl; // prints 0
    std::cout << (typeid(c) == typeid(d)) << std::endl; // prints 0

    return 0;






    share|improve this answer





























      0














      I am not sure whether I completely understand the problem, but since C++14 there is no need to use DEF_HOLDER two times. The following code also works:



      template <bool b>
      auto Func()
      return DEF_HOLDER(b);



      If you want a different type for every function call, you can add the int parameter:



      template <bool b, int i>
      auto Func()

      return Holder<b, i>();



      You could hide this int in a macro:



      #define FUNC(b) Func<b,__COUNTER__>();


      Then a,b and c,d have the same semantics:



      int main() 
      auto a = DEF_HOLDER(true);
      auto b = DEF_HOLDER(true);
      auto c = FUNC(true);
      auto d = FUNC(true);

      std::cout << (typeid(a) == typeid(b)) << std::endl; // prints 0
      std::cout << (typeid(c) == typeid(d)) << std::endl; // prints 0

      return 0;






      share|improve this answer



























        0












        0








        0







        I am not sure whether I completely understand the problem, but since C++14 there is no need to use DEF_HOLDER two times. The following code also works:



        template <bool b>
        auto Func()
        return DEF_HOLDER(b);



        If you want a different type for every function call, you can add the int parameter:



        template <bool b, int i>
        auto Func()

        return Holder<b, i>();



        You could hide this int in a macro:



        #define FUNC(b) Func<b,__COUNTER__>();


        Then a,b and c,d have the same semantics:



        int main() 
        auto a = DEF_HOLDER(true);
        auto b = DEF_HOLDER(true);
        auto c = FUNC(true);
        auto d = FUNC(true);

        std::cout << (typeid(a) == typeid(b)) << std::endl; // prints 0
        std::cout << (typeid(c) == typeid(d)) << std::endl; // prints 0

        return 0;






        share|improve this answer















        I am not sure whether I completely understand the problem, but since C++14 there is no need to use DEF_HOLDER two times. The following code also works:



        template <bool b>
        auto Func()
        return DEF_HOLDER(b);



        If you want a different type for every function call, you can add the int parameter:



        template <bool b, int i>
        auto Func()

        return Holder<b, i>();



        You could hide this int in a macro:



        #define FUNC(b) Func<b,__COUNTER__>();


        Then a,b and c,d have the same semantics:



        int main() 
        auto a = DEF_HOLDER(true);
        auto b = DEF_HOLDER(true);
        auto c = FUNC(true);
        auto d = FUNC(true);

        std::cout << (typeid(a) == typeid(b)) << std::endl; // prints 0
        std::cout << (typeid(c) == typeid(d)) << std::endl; // prints 0

        return 0;







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Feb 6 at 9:50

























        answered Feb 6 at 9:23









        Helmut ZeiselHelmut Zeisel

        1396




        1396



























            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%2f54548491%2ftype-deduction-time%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






            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay