Confusing templates in C++17 example of std::visit

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











up vote
6
down vote

favorite












When looking at std::visit() page in cppreference,
https://en.cppreference.com/w/cpp/utility/variant/visit, I encountered the code I can't make sense of...



Here's the abbreviated version:



#include <iomanip>
#include <iostream>
#include <string>
#include <type_traits>
#include <variant>
#include <vector>

using var_t = std::variant<int, long, double, std::string>;

template<class... Ts> struct overloaded : Ts... using Ts::operator()...; ;
template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;

int main()
std::vector<var_t> vec = 10, 15l, 1.5, "hello" ;
for (auto& v : vec)
std::visit(overloaded
(auto arg) std::cout << arg << ' '; ,
(double arg) std::cout << std::fixed << arg << ' '; ,
(const std::string& arg) std::cout << std::quoted(arg) << ' '; ,
, v);




What are the two lines declaring overloaded, just above int main(), mean?



Thank you for explaining!










share|improve this question























  • Anybody can shine some light on the initialization here? Why doesn't overloads(/* some lambdas */); work, but overloads/* some lambdas */; does? Notice the uniform initialization vs parentheses initialization.
    – Fureeish
    22 mins ago














up vote
6
down vote

favorite












When looking at std::visit() page in cppreference,
https://en.cppreference.com/w/cpp/utility/variant/visit, I encountered the code I can't make sense of...



Here's the abbreviated version:



#include <iomanip>
#include <iostream>
#include <string>
#include <type_traits>
#include <variant>
#include <vector>

using var_t = std::variant<int, long, double, std::string>;

template<class... Ts> struct overloaded : Ts... using Ts::operator()...; ;
template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;

int main()
std::vector<var_t> vec = 10, 15l, 1.5, "hello" ;
for (auto& v : vec)
std::visit(overloaded
(auto arg) std::cout << arg << ' '; ,
(double arg) std::cout << std::fixed << arg << ' '; ,
(const std::string& arg) std::cout << std::quoted(arg) << ' '; ,
, v);




What are the two lines declaring overloaded, just above int main(), mean?



Thank you for explaining!










share|improve this question























  • Anybody can shine some light on the initialization here? Why doesn't overloads(/* some lambdas */); work, but overloads/* some lambdas */; does? Notice the uniform initialization vs parentheses initialization.
    – Fureeish
    22 mins ago












up vote
6
down vote

favorite









up vote
6
down vote

favorite











When looking at std::visit() page in cppreference,
https://en.cppreference.com/w/cpp/utility/variant/visit, I encountered the code I can't make sense of...



Here's the abbreviated version:



#include <iomanip>
#include <iostream>
#include <string>
#include <type_traits>
#include <variant>
#include <vector>

using var_t = std::variant<int, long, double, std::string>;

template<class... Ts> struct overloaded : Ts... using Ts::operator()...; ;
template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;

int main()
std::vector<var_t> vec = 10, 15l, 1.5, "hello" ;
for (auto& v : vec)
std::visit(overloaded
(auto arg) std::cout << arg << ' '; ,
(double arg) std::cout << std::fixed << arg << ' '; ,
(const std::string& arg) std::cout << std::quoted(arg) << ' '; ,
, v);




What are the two lines declaring overloaded, just above int main(), mean?



Thank you for explaining!










share|improve this question















When looking at std::visit() page in cppreference,
https://en.cppreference.com/w/cpp/utility/variant/visit, I encountered the code I can't make sense of...



Here's the abbreviated version:



#include <iomanip>
#include <iostream>
#include <string>
#include <type_traits>
#include <variant>
#include <vector>

using var_t = std::variant<int, long, double, std::string>;

template<class... Ts> struct overloaded : Ts... using Ts::operator()...; ;
template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;

int main()
std::vector<var_t> vec = 10, 15l, 1.5, "hello" ;
for (auto& v : vec)
std::visit(overloaded
(auto arg) std::cout << arg << ' '; ,
(double arg) std::cout << std::fixed << arg << ' '; ,
(const std::string& arg) std::cout << std::quoted(arg) << ' '; ,
, v);




What are the two lines declaring overloaded, just above int main(), mean?



Thank you for explaining!







c++ templates c++17 variadic-templates






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 54 mins ago









max66

29.7k63156




29.7k63156










asked 1 hour ago









Boris

8818




8818











  • Anybody can shine some light on the initialization here? Why doesn't overloads(/* some lambdas */); work, but overloads/* some lambdas */; does? Notice the uniform initialization vs parentheses initialization.
    – Fureeish
    22 mins ago
















  • Anybody can shine some light on the initialization here? Why doesn't overloads(/* some lambdas */); work, but overloads/* some lambdas */; does? Notice the uniform initialization vs parentheses initialization.
    – Fureeish
    22 mins ago















Anybody can shine some light on the initialization here? Why doesn't overloads(/* some lambdas */); work, but overloads/* some lambdas */; does? Notice the uniform initialization vs parentheses initialization.
– Fureeish
22 mins ago




Anybody can shine some light on the initialization here? Why doesn't overloads(/* some lambdas */); work, but overloads/* some lambdas */; does? Notice the uniform initialization vs parentheses initialization.
– Fureeish
22 mins ago












2 Answers
2






active

oldest

votes

















up vote
6
down vote



accepted










Ahh, I love this.



It's a way to concisely declare a struct with a call operator overloaded on the set of the template arguments call operators.



template<class... Ts> struct overloaded : Ts... using Ts::operator()...; ;


overloaded inherits from Ts... and uses all of their operator()



template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;


This is a deduction guide so you don't specify the template parameters



The usage is as you see in the example.



It's a nice utility to create an overloaded set of multiple lambdas (and other function types).




Previous to C++17 you would have to use recursion to create overload. Not pretty:



template <class... Fs> struct Overload : Fs...

;

template <class Head, class... Tail>
struct Overload<Head, Tail...> : Head, Overload<Tail...>

Overload(Head head, Tail... tail)
: Headhead, Overload<Tail...>tail...


using Head::operator();
using Overload<Tail...>::operator();
;


template <class F> struct Overload<F> : F

Overload(F f) : Ff

using F::operator();
;


template <class... Fs> auto make_overload_set(Fs... fs)

return Overload<Fs...>fs...;


auto test()

auto o = make_overload_set(
(int) return 24; ,
(char) return 11; );

o(2); // returns 24
o('a'); // return 11



The main nuisance is that Overload because inherits is not an aggregate, so you need to do the recursion trick to create a constructor with all the types. In C++17 overloaded is an aggregate (yey) so constructing one works out of the box :). You also need to specify using::operator() for each of them.






share|improve this answer






















  • You missed the worst part! using Head::operator(); using Overload<Tail..>::operator();
    – Barry
    44 mins ago










  • @Barry clang compiles it without using, so I just assumed it's something about inheriting one by one that makes that possible. After your comment I double checked and gcc complains about ambiguity, so maybe it's a clang "feature". Will correct in answer.
    – bolov
    26 mins ago










  • Yeah, alternatively a clang bug :-)
    – Barry
    22 mins ago

















up vote
5
down vote














What are the two lines declaring overloaded, just above int main(), mean?




The first one



template<class... Ts>
struct overloaded : Ts...
using Ts::operator()...; ;


is a classic class/struct declaration/definition/implementation. Valid from C++11 (because use variadic templates).



In this case, overload inherit from all template parameters and enable (using row) all inherited operator().



Unfortunately the variadic using is available only starting from C++17.



The second one



template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;


is a "deduction guide" (see this page for more details) and it's a new C++17 feature.



In your case, the deduction guide say that when you write something as



auto ov = overloaded arg1, arg2, arg3, arg4 ;


or also



overloaded ov arg1, args, arg3, arg4 ;


ov become a overloaded<decltype(arg1), decltype(arg2), decltype(arg3), decltype(arg4)>



This permit you to write something as



 overloaded
(auto arg) std::cout << arg << ' '; ,
(double arg) std::cout << std::fixed << arg << ' '; ,
(const std::string& arg) std::cout << std::quoted(arg) << ' '; ,



that in C++14 was



auto l1 = (auto arg) std::cout << arg << ' '; ;
auto l2 = (double arg) std::cout << std::fixed << arg << ' '; ;
auto l3 = (const std::string& arg) std::cout << std::quoted(arg) << ' ';

overloaded<decltype(l1), decltype(l2), decltype(l3)> ovl1, l2, l3;





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',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    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%2f52523816%2fconfusing-templates-in-c17-example-of-stdvisit%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    6
    down vote



    accepted










    Ahh, I love this.



    It's a way to concisely declare a struct with a call operator overloaded on the set of the template arguments call operators.



    template<class... Ts> struct overloaded : Ts... using Ts::operator()...; ;


    overloaded inherits from Ts... and uses all of their operator()



    template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;


    This is a deduction guide so you don't specify the template parameters



    The usage is as you see in the example.



    It's a nice utility to create an overloaded set of multiple lambdas (and other function types).




    Previous to C++17 you would have to use recursion to create overload. Not pretty:



    template <class... Fs> struct Overload : Fs...

    ;

    template <class Head, class... Tail>
    struct Overload<Head, Tail...> : Head, Overload<Tail...>

    Overload(Head head, Tail... tail)
    : Headhead, Overload<Tail...>tail...


    using Head::operator();
    using Overload<Tail...>::operator();
    ;


    template <class F> struct Overload<F> : F

    Overload(F f) : Ff

    using F::operator();
    ;


    template <class... Fs> auto make_overload_set(Fs... fs)

    return Overload<Fs...>fs...;


    auto test()

    auto o = make_overload_set(
    (int) return 24; ,
    (char) return 11; );

    o(2); // returns 24
    o('a'); // return 11



    The main nuisance is that Overload because inherits is not an aggregate, so you need to do the recursion trick to create a constructor with all the types. In C++17 overloaded is an aggregate (yey) so constructing one works out of the box :). You also need to specify using::operator() for each of them.






    share|improve this answer






















    • You missed the worst part! using Head::operator(); using Overload<Tail..>::operator();
      – Barry
      44 mins ago










    • @Barry clang compiles it without using, so I just assumed it's something about inheriting one by one that makes that possible. After your comment I double checked and gcc complains about ambiguity, so maybe it's a clang "feature". Will correct in answer.
      – bolov
      26 mins ago










    • Yeah, alternatively a clang bug :-)
      – Barry
      22 mins ago














    up vote
    6
    down vote



    accepted










    Ahh, I love this.



    It's a way to concisely declare a struct with a call operator overloaded on the set of the template arguments call operators.



    template<class... Ts> struct overloaded : Ts... using Ts::operator()...; ;


    overloaded inherits from Ts... and uses all of their operator()



    template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;


    This is a deduction guide so you don't specify the template parameters



    The usage is as you see in the example.



    It's a nice utility to create an overloaded set of multiple lambdas (and other function types).




    Previous to C++17 you would have to use recursion to create overload. Not pretty:



    template <class... Fs> struct Overload : Fs...

    ;

    template <class Head, class... Tail>
    struct Overload<Head, Tail...> : Head, Overload<Tail...>

    Overload(Head head, Tail... tail)
    : Headhead, Overload<Tail...>tail...


    using Head::operator();
    using Overload<Tail...>::operator();
    ;


    template <class F> struct Overload<F> : F

    Overload(F f) : Ff

    using F::operator();
    ;


    template <class... Fs> auto make_overload_set(Fs... fs)

    return Overload<Fs...>fs...;


    auto test()

    auto o = make_overload_set(
    (int) return 24; ,
    (char) return 11; );

    o(2); // returns 24
    o('a'); // return 11



    The main nuisance is that Overload because inherits is not an aggregate, so you need to do the recursion trick to create a constructor with all the types. In C++17 overloaded is an aggregate (yey) so constructing one works out of the box :). You also need to specify using::operator() for each of them.






    share|improve this answer






















    • You missed the worst part! using Head::operator(); using Overload<Tail..>::operator();
      – Barry
      44 mins ago










    • @Barry clang compiles it without using, so I just assumed it's something about inheriting one by one that makes that possible. After your comment I double checked and gcc complains about ambiguity, so maybe it's a clang "feature". Will correct in answer.
      – bolov
      26 mins ago










    • Yeah, alternatively a clang bug :-)
      – Barry
      22 mins ago












    up vote
    6
    down vote



    accepted







    up vote
    6
    down vote



    accepted






    Ahh, I love this.



    It's a way to concisely declare a struct with a call operator overloaded on the set of the template arguments call operators.



    template<class... Ts> struct overloaded : Ts... using Ts::operator()...; ;


    overloaded inherits from Ts... and uses all of their operator()



    template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;


    This is a deduction guide so you don't specify the template parameters



    The usage is as you see in the example.



    It's a nice utility to create an overloaded set of multiple lambdas (and other function types).




    Previous to C++17 you would have to use recursion to create overload. Not pretty:



    template <class... Fs> struct Overload : Fs...

    ;

    template <class Head, class... Tail>
    struct Overload<Head, Tail...> : Head, Overload<Tail...>

    Overload(Head head, Tail... tail)
    : Headhead, Overload<Tail...>tail...


    using Head::operator();
    using Overload<Tail...>::operator();
    ;


    template <class F> struct Overload<F> : F

    Overload(F f) : Ff

    using F::operator();
    ;


    template <class... Fs> auto make_overload_set(Fs... fs)

    return Overload<Fs...>fs...;


    auto test()

    auto o = make_overload_set(
    (int) return 24; ,
    (char) return 11; );

    o(2); // returns 24
    o('a'); // return 11



    The main nuisance is that Overload because inherits is not an aggregate, so you need to do the recursion trick to create a constructor with all the types. In C++17 overloaded is an aggregate (yey) so constructing one works out of the box :). You also need to specify using::operator() for each of them.






    share|improve this answer














    Ahh, I love this.



    It's a way to concisely declare a struct with a call operator overloaded on the set of the template arguments call operators.



    template<class... Ts> struct overloaded : Ts... using Ts::operator()...; ;


    overloaded inherits from Ts... and uses all of their operator()



    template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;


    This is a deduction guide so you don't specify the template parameters



    The usage is as you see in the example.



    It's a nice utility to create an overloaded set of multiple lambdas (and other function types).




    Previous to C++17 you would have to use recursion to create overload. Not pretty:



    template <class... Fs> struct Overload : Fs...

    ;

    template <class Head, class... Tail>
    struct Overload<Head, Tail...> : Head, Overload<Tail...>

    Overload(Head head, Tail... tail)
    : Headhead, Overload<Tail...>tail...


    using Head::operator();
    using Overload<Tail...>::operator();
    ;


    template <class F> struct Overload<F> : F

    Overload(F f) : Ff

    using F::operator();
    ;


    template <class... Fs> auto make_overload_set(Fs... fs)

    return Overload<Fs...>fs...;


    auto test()

    auto o = make_overload_set(
    (int) return 24; ,
    (char) return 11; );

    o(2); // returns 24
    o('a'); // return 11



    The main nuisance is that Overload because inherits is not an aggregate, so you need to do the recursion trick to create a constructor with all the types. In C++17 overloaded is an aggregate (yey) so constructing one works out of the box :). You also need to specify using::operator() for each of them.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 23 mins ago

























    answered 1 hour ago









    bolov

    27.7k663119




    27.7k663119











    • You missed the worst part! using Head::operator(); using Overload<Tail..>::operator();
      – Barry
      44 mins ago










    • @Barry clang compiles it without using, so I just assumed it's something about inheriting one by one that makes that possible. After your comment I double checked and gcc complains about ambiguity, so maybe it's a clang "feature". Will correct in answer.
      – bolov
      26 mins ago










    • Yeah, alternatively a clang bug :-)
      – Barry
      22 mins ago
















    • You missed the worst part! using Head::operator(); using Overload<Tail..>::operator();
      – Barry
      44 mins ago










    • @Barry clang compiles it without using, so I just assumed it's something about inheriting one by one that makes that possible. After your comment I double checked and gcc complains about ambiguity, so maybe it's a clang "feature". Will correct in answer.
      – bolov
      26 mins ago










    • Yeah, alternatively a clang bug :-)
      – Barry
      22 mins ago















    You missed the worst part! using Head::operator(); using Overload<Tail..>::operator();
    – Barry
    44 mins ago




    You missed the worst part! using Head::operator(); using Overload<Tail..>::operator();
    – Barry
    44 mins ago












    @Barry clang compiles it without using, so I just assumed it's something about inheriting one by one that makes that possible. After your comment I double checked and gcc complains about ambiguity, so maybe it's a clang "feature". Will correct in answer.
    – bolov
    26 mins ago




    @Barry clang compiles it without using, so I just assumed it's something about inheriting one by one that makes that possible. After your comment I double checked and gcc complains about ambiguity, so maybe it's a clang "feature". Will correct in answer.
    – bolov
    26 mins ago












    Yeah, alternatively a clang bug :-)
    – Barry
    22 mins ago




    Yeah, alternatively a clang bug :-)
    – Barry
    22 mins ago












    up vote
    5
    down vote














    What are the two lines declaring overloaded, just above int main(), mean?




    The first one



    template<class... Ts>
    struct overloaded : Ts...
    using Ts::operator()...; ;


    is a classic class/struct declaration/definition/implementation. Valid from C++11 (because use variadic templates).



    In this case, overload inherit from all template parameters and enable (using row) all inherited operator().



    Unfortunately the variadic using is available only starting from C++17.



    The second one



    template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;


    is a "deduction guide" (see this page for more details) and it's a new C++17 feature.



    In your case, the deduction guide say that when you write something as



    auto ov = overloaded arg1, arg2, arg3, arg4 ;


    or also



    overloaded ov arg1, args, arg3, arg4 ;


    ov become a overloaded<decltype(arg1), decltype(arg2), decltype(arg3), decltype(arg4)>



    This permit you to write something as



     overloaded
    (auto arg) std::cout << arg << ' '; ,
    (double arg) std::cout << std::fixed << arg << ' '; ,
    (const std::string& arg) std::cout << std::quoted(arg) << ' '; ,



    that in C++14 was



    auto l1 = (auto arg) std::cout << arg << ' '; ;
    auto l2 = (double arg) std::cout << std::fixed << arg << ' '; ;
    auto l3 = (const std::string& arg) std::cout << std::quoted(arg) << ' ';

    overloaded<decltype(l1), decltype(l2), decltype(l3)> ovl1, l2, l3;





    share|improve this answer


























      up vote
      5
      down vote














      What are the two lines declaring overloaded, just above int main(), mean?




      The first one



      template<class... Ts>
      struct overloaded : Ts...
      using Ts::operator()...; ;


      is a classic class/struct declaration/definition/implementation. Valid from C++11 (because use variadic templates).



      In this case, overload inherit from all template parameters and enable (using row) all inherited operator().



      Unfortunately the variadic using is available only starting from C++17.



      The second one



      template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;


      is a "deduction guide" (see this page for more details) and it's a new C++17 feature.



      In your case, the deduction guide say that when you write something as



      auto ov = overloaded arg1, arg2, arg3, arg4 ;


      or also



      overloaded ov arg1, args, arg3, arg4 ;


      ov become a overloaded<decltype(arg1), decltype(arg2), decltype(arg3), decltype(arg4)>



      This permit you to write something as



       overloaded
      (auto arg) std::cout << arg << ' '; ,
      (double arg) std::cout << std::fixed << arg << ' '; ,
      (const std::string& arg) std::cout << std::quoted(arg) << ' '; ,



      that in C++14 was



      auto l1 = (auto arg) std::cout << arg << ' '; ;
      auto l2 = (double arg) std::cout << std::fixed << arg << ' '; ;
      auto l3 = (const std::string& arg) std::cout << std::quoted(arg) << ' ';

      overloaded<decltype(l1), decltype(l2), decltype(l3)> ovl1, l2, l3;





      share|improve this answer
























        up vote
        5
        down vote










        up vote
        5
        down vote










        What are the two lines declaring overloaded, just above int main(), mean?




        The first one



        template<class... Ts>
        struct overloaded : Ts...
        using Ts::operator()...; ;


        is a classic class/struct declaration/definition/implementation. Valid from C++11 (because use variadic templates).



        In this case, overload inherit from all template parameters and enable (using row) all inherited operator().



        Unfortunately the variadic using is available only starting from C++17.



        The second one



        template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;


        is a "deduction guide" (see this page for more details) and it's a new C++17 feature.



        In your case, the deduction guide say that when you write something as



        auto ov = overloaded arg1, arg2, arg3, arg4 ;


        or also



        overloaded ov arg1, args, arg3, arg4 ;


        ov become a overloaded<decltype(arg1), decltype(arg2), decltype(arg3), decltype(arg4)>



        This permit you to write something as



         overloaded
        (auto arg) std::cout << arg << ' '; ,
        (double arg) std::cout << std::fixed << arg << ' '; ,
        (const std::string& arg) std::cout << std::quoted(arg) << ' '; ,



        that in C++14 was



        auto l1 = (auto arg) std::cout << arg << ' '; ;
        auto l2 = (double arg) std::cout << std::fixed << arg << ' '; ;
        auto l3 = (const std::string& arg) std::cout << std::quoted(arg) << ' ';

        overloaded<decltype(l1), decltype(l2), decltype(l3)> ovl1, l2, l3;





        share|improve this answer















        What are the two lines declaring overloaded, just above int main(), mean?




        The first one



        template<class... Ts>
        struct overloaded : Ts...
        using Ts::operator()...; ;


        is a classic class/struct declaration/definition/implementation. Valid from C++11 (because use variadic templates).



        In this case, overload inherit from all template parameters and enable (using row) all inherited operator().



        Unfortunately the variadic using is available only starting from C++17.



        The second one



        template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;


        is a "deduction guide" (see this page for more details) and it's a new C++17 feature.



        In your case, the deduction guide say that when you write something as



        auto ov = overloaded arg1, arg2, arg3, arg4 ;


        or also



        overloaded ov arg1, args, arg3, arg4 ;


        ov become a overloaded<decltype(arg1), decltype(arg2), decltype(arg3), decltype(arg4)>



        This permit you to write something as



         overloaded
        (auto arg) std::cout << arg << ' '; ,
        (double arg) std::cout << std::fixed << arg << ' '; ,
        (const std::string& arg) std::cout << std::quoted(arg) << ' '; ,



        that in C++14 was



        auto l1 = (auto arg) std::cout << arg << ' '; ;
        auto l2 = (double arg) std::cout << std::fixed << arg << ' '; ;
        auto l3 = (const std::string& arg) std::cout << std::quoted(arg) << ' ';

        overloaded<decltype(l1), decltype(l2), decltype(l3)> ovl1, l2, l3;






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 52 mins ago

























        answered 1 hour ago









        max66

        29.7k63156




        29.7k63156



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52523816%2fconfusing-templates-in-c17-example-of-stdvisit%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            Long meetings (6-7 hours a day): Being “babysat” by supervisor

            What does second last employer means? [closed]

            One-line joke