Shorthand for overloading multiple functions












2















Assuming I have code such as the one below:



bool isString(char* arg) { return true; }
bool isString(const char* arg) { return true; }
bool isString(std::string arg) { return true; }

// Any other type...
template <typename type> bool isString(type arg) { return false; }


The question is, does C++ allow for any plausible way to shorten the syntax below to something similar to the concept below (syntactic shorthand/ sugar):



// Could be `char*`, `const char*` or `std::string` here.
bool isString([char*, const char*, std::string] arg) { return true; }

// Any other type...
template <typename type> bool isString(type arg) { return false; }


The examples presented here are not necessarily for detecting strings, but rather to explain the problem of multiple lines of code being dedicated to overloaded functions.



Imagine if I had to test for a 100+ data types for if they were valid or not, I would quickly want a shorter way of coding this rather than typing all 100 overloaded functions



Of course, the drawback to this syntactic shorthand is the fact that the data type of arg can not then be differentiated (unlike with the standard function overloading).










share|improve this question

























  • For numeric types, there is std::is_arithmetic.

    – halfelf
    Nov 21 '18 at 6:03






  • 1





    If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.

    – StoryTeller
    Nov 21 '18 at 6:05






  • 1





    @JesperJuhl - isNumber(std::vector<std::string>{})?

    – StoryTeller
    Nov 21 '18 at 6:06






  • 1





    The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.

    – Lapys
    Nov 21 '18 at 6:11








  • 1





    My point is that you don't need a function. You need a variable template template<class> bool is_string and you need to pass it the type of the thing you want to check, not the thing itself.

    – n.m.
    Nov 21 '18 at 10:48
















2















Assuming I have code such as the one below:



bool isString(char* arg) { return true; }
bool isString(const char* arg) { return true; }
bool isString(std::string arg) { return true; }

// Any other type...
template <typename type> bool isString(type arg) { return false; }


The question is, does C++ allow for any plausible way to shorten the syntax below to something similar to the concept below (syntactic shorthand/ sugar):



// Could be `char*`, `const char*` or `std::string` here.
bool isString([char*, const char*, std::string] arg) { return true; }

// Any other type...
template <typename type> bool isString(type arg) { return false; }


The examples presented here are not necessarily for detecting strings, but rather to explain the problem of multiple lines of code being dedicated to overloaded functions.



Imagine if I had to test for a 100+ data types for if they were valid or not, I would quickly want a shorter way of coding this rather than typing all 100 overloaded functions



Of course, the drawback to this syntactic shorthand is the fact that the data type of arg can not then be differentiated (unlike with the standard function overloading).










share|improve this question

























  • For numeric types, there is std::is_arithmetic.

    – halfelf
    Nov 21 '18 at 6:03






  • 1





    If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.

    – StoryTeller
    Nov 21 '18 at 6:05






  • 1





    @JesperJuhl - isNumber(std::vector<std::string>{})?

    – StoryTeller
    Nov 21 '18 at 6:06






  • 1





    The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.

    – Lapys
    Nov 21 '18 at 6:11








  • 1





    My point is that you don't need a function. You need a variable template template<class> bool is_string and you need to pass it the type of the thing you want to check, not the thing itself.

    – n.m.
    Nov 21 '18 at 10:48














2












2








2








Assuming I have code such as the one below:



bool isString(char* arg) { return true; }
bool isString(const char* arg) { return true; }
bool isString(std::string arg) { return true; }

// Any other type...
template <typename type> bool isString(type arg) { return false; }


The question is, does C++ allow for any plausible way to shorten the syntax below to something similar to the concept below (syntactic shorthand/ sugar):



// Could be `char*`, `const char*` or `std::string` here.
bool isString([char*, const char*, std::string] arg) { return true; }

// Any other type...
template <typename type> bool isString(type arg) { return false; }


The examples presented here are not necessarily for detecting strings, but rather to explain the problem of multiple lines of code being dedicated to overloaded functions.



Imagine if I had to test for a 100+ data types for if they were valid or not, I would quickly want a shorter way of coding this rather than typing all 100 overloaded functions



Of course, the drawback to this syntactic shorthand is the fact that the data type of arg can not then be differentiated (unlike with the standard function overloading).










share|improve this question
















Assuming I have code such as the one below:



bool isString(char* arg) { return true; }
bool isString(const char* arg) { return true; }
bool isString(std::string arg) { return true; }

// Any other type...
template <typename type> bool isString(type arg) { return false; }


The question is, does C++ allow for any plausible way to shorten the syntax below to something similar to the concept below (syntactic shorthand/ sugar):



// Could be `char*`, `const char*` or `std::string` here.
bool isString([char*, const char*, std::string] arg) { return true; }

// Any other type...
template <typename type> bool isString(type arg) { return false; }


The examples presented here are not necessarily for detecting strings, but rather to explain the problem of multiple lines of code being dedicated to overloaded functions.



Imagine if I had to test for a 100+ data types for if they were valid or not, I would quickly want a shorter way of coding this rather than typing all 100 overloaded functions



Of course, the drawback to this syntactic shorthand is the fact that the data type of arg can not then be differentiated (unlike with the standard function overloading).







c++ function-overloading






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 21:21









halfer

14.5k758111




14.5k758111










asked Nov 21 '18 at 5:56









LapysLapys

3961313




3961313













  • For numeric types, there is std::is_arithmetic.

    – halfelf
    Nov 21 '18 at 6:03






  • 1





    If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.

    – StoryTeller
    Nov 21 '18 at 6:05






  • 1





    @JesperJuhl - isNumber(std::vector<std::string>{})?

    – StoryTeller
    Nov 21 '18 at 6:06






  • 1





    The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.

    – Lapys
    Nov 21 '18 at 6:11








  • 1





    My point is that you don't need a function. You need a variable template template<class> bool is_string and you need to pass it the type of the thing you want to check, not the thing itself.

    – n.m.
    Nov 21 '18 at 10:48



















  • For numeric types, there is std::is_arithmetic.

    – halfelf
    Nov 21 '18 at 6:03






  • 1





    If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.

    – StoryTeller
    Nov 21 '18 at 6:05






  • 1





    @JesperJuhl - isNumber(std::vector<std::string>{})?

    – StoryTeller
    Nov 21 '18 at 6:06






  • 1





    The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.

    – Lapys
    Nov 21 '18 at 6:11








  • 1





    My point is that you don't need a function. You need a variable template template<class> bool is_string and you need to pass it the type of the thing you want to check, not the thing itself.

    – n.m.
    Nov 21 '18 at 10:48

















For numeric types, there is std::is_arithmetic.

– halfelf
Nov 21 '18 at 6:03





For numeric types, there is std::is_arithmetic.

– halfelf
Nov 21 '18 at 6:03




1




1





If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.

– StoryTeller
Nov 21 '18 at 6:05





If you need to differentiate the actual argument type than collapsing overloads into a template is not something you should do.

– StoryTeller
Nov 21 '18 at 6:05




1




1





@JesperJuhl - isNumber(std::vector<std::string>{})?

– StoryTeller
Nov 21 '18 at 6:06





@JesperJuhl - isNumber(std::vector<std::string>{})?

– StoryTeller
Nov 21 '18 at 6:06




1




1





The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.

– Lapys
Nov 21 '18 at 6:11







The question is asking if there is a way to collapse multiple overloaded function statements into a single statement. Syntactic sugar basically.

– Lapys
Nov 21 '18 at 6:11






1




1





My point is that you don't need a function. You need a variable template template<class> bool is_string and you need to pass it the type of the thing you want to check, not the thing itself.

– n.m.
Nov 21 '18 at 10:48





My point is that you don't need a function. You need a variable template template<class> bool is_string and you need to pass it the type of the thing you want to check, not the thing itself.

– n.m.
Nov 21 '18 at 10:48












4 Answers
4






active

oldest

votes


















1














A function is not needed here, because the value of the argument is always ignored. A (const) variable template is enough.



#include <string>
#include <iostream>
template <class> const bool is_string = false;
template<> const bool is_string<const char*> = true;
template<> const bool is_string<std::string> = true;

int main() {
const char* z;
std::string p;
int q;

std::cout << is_string<decltype(z)> << "n";
std::cout << is_string<decltype(p)> << "n";
std::cout << is_string<decltype(q)> << "n";
}


If a function interface is desired, it's trivial to provide



 template<class T>
constexpr bool is_string_f(const T&) {
return is_string<T>;
}


OK you say, all these specialisations are still too long to write, can we shorten them more? Yes we can.



#include <type_traits>
template<class X, class ... args>
const bool type_is_one_of = (false || ... || std::is_same<X, args>::value);
template <class T>
bool is_string = type_is_one_of<T, char*, const char*, std::string>;


Live example on ideone.






share|improve this answer

































    5














    Probably the best approach would be to start with defining a trait identifying your types:



    template<typename> struct is_string : std::false_type{};

    template<> struct is_string<char*> : std::true_type{};
    template<> struct is_string<char const*> : std::true_type{};
    template<> struct is_string<std::string> : std::true_type{};


    Then you can do all sorts of stuff. For instance, implementing the function in your post becomes this



    template<typename T> constexpr bool isString(T) { return is_string<T>::value; }


    Or if you want to control overload resolution, and remove a function from an overload set when the argument isn't a string as we view it:



    template<typename S>
    auto needAString(S s) -> std::enable_if_t<is_string<S>::value>;




    Some pre-defined traits and utilities are already available in the <type_traits> header.






    share|improve this answer
























    • I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.

      – Lapys
      Nov 21 '18 at 6:37






    • 1





      @Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?

      – StoryTeller
      Nov 21 '18 at 6:40













    • Ah, I see. Thanks.

      – Lapys
      Nov 21 '18 at 6:42








    • 1





      @Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functions constexpr may move them into the same direction but making such type traits will probably work better in general.

      – Scheff
      Nov 21 '18 at 6:47



















    2














    Might



    #include <type_traits>
    #include <string>

    template<typename T>
    bool is_string(T)
    {
    return std::is_constructible<std::string, T>::value;
    }


    be enough?






    share|improve this answer































      1














      You might directly do:



      template <typename T>
      constexpr bool isString()
      {
      return std::is_same<T, const char*>::value
      || std::is_same<T, char*>::value
      || std::is_same<T, std::string>::value;
      }


      then if you have to set of overloads, you might use SFINAE:



      template <typename T>
      std::enable_if_t<isString<T>()> foo(/**/) { /*..*/}

      template <typename T>
      std::enable_if_t<!isString<T>()> foo(/**/) { /*..*/}


      or if constexpr (c++17):



      template <typename T>
      void foo(/**/)
      {
      if constexpr (isString<T>()) {
      /*..*/
      } else {
      /*..*/
      }
      }





      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%2f53406038%2fshorthand-for-overloading-multiple-functions%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        1














        A function is not needed here, because the value of the argument is always ignored. A (const) variable template is enough.



        #include <string>
        #include <iostream>
        template <class> const bool is_string = false;
        template<> const bool is_string<const char*> = true;
        template<> const bool is_string<std::string> = true;

        int main() {
        const char* z;
        std::string p;
        int q;

        std::cout << is_string<decltype(z)> << "n";
        std::cout << is_string<decltype(p)> << "n";
        std::cout << is_string<decltype(q)> << "n";
        }


        If a function interface is desired, it's trivial to provide



         template<class T>
        constexpr bool is_string_f(const T&) {
        return is_string<T>;
        }


        OK you say, all these specialisations are still too long to write, can we shorten them more? Yes we can.



        #include <type_traits>
        template<class X, class ... args>
        const bool type_is_one_of = (false || ... || std::is_same<X, args>::value);
        template <class T>
        bool is_string = type_is_one_of<T, char*, const char*, std::string>;


        Live example on ideone.






        share|improve this answer






























          1














          A function is not needed here, because the value of the argument is always ignored. A (const) variable template is enough.



          #include <string>
          #include <iostream>
          template <class> const bool is_string = false;
          template<> const bool is_string<const char*> = true;
          template<> const bool is_string<std::string> = true;

          int main() {
          const char* z;
          std::string p;
          int q;

          std::cout << is_string<decltype(z)> << "n";
          std::cout << is_string<decltype(p)> << "n";
          std::cout << is_string<decltype(q)> << "n";
          }


          If a function interface is desired, it's trivial to provide



           template<class T>
          constexpr bool is_string_f(const T&) {
          return is_string<T>;
          }


          OK you say, all these specialisations are still too long to write, can we shorten them more? Yes we can.



          #include <type_traits>
          template<class X, class ... args>
          const bool type_is_one_of = (false || ... || std::is_same<X, args>::value);
          template <class T>
          bool is_string = type_is_one_of<T, char*, const char*, std::string>;


          Live example on ideone.






          share|improve this answer




























            1












            1








            1







            A function is not needed here, because the value of the argument is always ignored. A (const) variable template is enough.



            #include <string>
            #include <iostream>
            template <class> const bool is_string = false;
            template<> const bool is_string<const char*> = true;
            template<> const bool is_string<std::string> = true;

            int main() {
            const char* z;
            std::string p;
            int q;

            std::cout << is_string<decltype(z)> << "n";
            std::cout << is_string<decltype(p)> << "n";
            std::cout << is_string<decltype(q)> << "n";
            }


            If a function interface is desired, it's trivial to provide



             template<class T>
            constexpr bool is_string_f(const T&) {
            return is_string<T>;
            }


            OK you say, all these specialisations are still too long to write, can we shorten them more? Yes we can.



            #include <type_traits>
            template<class X, class ... args>
            const bool type_is_one_of = (false || ... || std::is_same<X, args>::value);
            template <class T>
            bool is_string = type_is_one_of<T, char*, const char*, std::string>;


            Live example on ideone.






            share|improve this answer















            A function is not needed here, because the value of the argument is always ignored. A (const) variable template is enough.



            #include <string>
            #include <iostream>
            template <class> const bool is_string = false;
            template<> const bool is_string<const char*> = true;
            template<> const bool is_string<std::string> = true;

            int main() {
            const char* z;
            std::string p;
            int q;

            std::cout << is_string<decltype(z)> << "n";
            std::cout << is_string<decltype(p)> << "n";
            std::cout << is_string<decltype(q)> << "n";
            }


            If a function interface is desired, it's trivial to provide



             template<class T>
            constexpr bool is_string_f(const T&) {
            return is_string<T>;
            }


            OK you say, all these specialisations are still too long to write, can we shorten them more? Yes we can.



            #include <type_traits>
            template<class X, class ... args>
            const bool type_is_one_of = (false || ... || std::is_same<X, args>::value);
            template <class T>
            bool is_string = type_is_one_of<T, char*, const char*, std::string>;


            Live example on ideone.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 21 '18 at 11:13

























            answered Nov 21 '18 at 11:06









            n.m.n.m.

            71.9k882167




            71.9k882167

























                5














                Probably the best approach would be to start with defining a trait identifying your types:



                template<typename> struct is_string : std::false_type{};

                template<> struct is_string<char*> : std::true_type{};
                template<> struct is_string<char const*> : std::true_type{};
                template<> struct is_string<std::string> : std::true_type{};


                Then you can do all sorts of stuff. For instance, implementing the function in your post becomes this



                template<typename T> constexpr bool isString(T) { return is_string<T>::value; }


                Or if you want to control overload resolution, and remove a function from an overload set when the argument isn't a string as we view it:



                template<typename S>
                auto needAString(S s) -> std::enable_if_t<is_string<S>::value>;




                Some pre-defined traits and utilities are already available in the <type_traits> header.






                share|improve this answer
























                • I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.

                  – Lapys
                  Nov 21 '18 at 6:37






                • 1





                  @Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?

                  – StoryTeller
                  Nov 21 '18 at 6:40













                • Ah, I see. Thanks.

                  – Lapys
                  Nov 21 '18 at 6:42








                • 1





                  @Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functions constexpr may move them into the same direction but making such type traits will probably work better in general.

                  – Scheff
                  Nov 21 '18 at 6:47
















                5














                Probably the best approach would be to start with defining a trait identifying your types:



                template<typename> struct is_string : std::false_type{};

                template<> struct is_string<char*> : std::true_type{};
                template<> struct is_string<char const*> : std::true_type{};
                template<> struct is_string<std::string> : std::true_type{};


                Then you can do all sorts of stuff. For instance, implementing the function in your post becomes this



                template<typename T> constexpr bool isString(T) { return is_string<T>::value; }


                Or if you want to control overload resolution, and remove a function from an overload set when the argument isn't a string as we view it:



                template<typename S>
                auto needAString(S s) -> std::enable_if_t<is_string<S>::value>;




                Some pre-defined traits and utilities are already available in the <type_traits> header.






                share|improve this answer
























                • I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.

                  – Lapys
                  Nov 21 '18 at 6:37






                • 1





                  @Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?

                  – StoryTeller
                  Nov 21 '18 at 6:40













                • Ah, I see. Thanks.

                  – Lapys
                  Nov 21 '18 at 6:42








                • 1





                  @Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functions constexpr may move them into the same direction but making such type traits will probably work better in general.

                  – Scheff
                  Nov 21 '18 at 6:47














                5












                5








                5







                Probably the best approach would be to start with defining a trait identifying your types:



                template<typename> struct is_string : std::false_type{};

                template<> struct is_string<char*> : std::true_type{};
                template<> struct is_string<char const*> : std::true_type{};
                template<> struct is_string<std::string> : std::true_type{};


                Then you can do all sorts of stuff. For instance, implementing the function in your post becomes this



                template<typename T> constexpr bool isString(T) { return is_string<T>::value; }


                Or if you want to control overload resolution, and remove a function from an overload set when the argument isn't a string as we view it:



                template<typename S>
                auto needAString(S s) -> std::enable_if_t<is_string<S>::value>;




                Some pre-defined traits and utilities are already available in the <type_traits> header.






                share|improve this answer













                Probably the best approach would be to start with defining a trait identifying your types:



                template<typename> struct is_string : std::false_type{};

                template<> struct is_string<char*> : std::true_type{};
                template<> struct is_string<char const*> : std::true_type{};
                template<> struct is_string<std::string> : std::true_type{};


                Then you can do all sorts of stuff. For instance, implementing the function in your post becomes this



                template<typename T> constexpr bool isString(T) { return is_string<T>::value; }


                Or if you want to control overload resolution, and remove a function from an overload set when the argument isn't a string as we view it:



                template<typename S>
                auto needAString(S s) -> std::enable_if_t<is_string<S>::value>;




                Some pre-defined traits and utilities are already available in the <type_traits> header.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 21 '18 at 6:24









                StoryTellerStoryTeller

                97.9k12199267




                97.9k12199267













                • I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.

                  – Lapys
                  Nov 21 '18 at 6:37






                • 1





                  @Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?

                  – StoryTeller
                  Nov 21 '18 at 6:40













                • Ah, I see. Thanks.

                  – Lapys
                  Nov 21 '18 at 6:42








                • 1





                  @Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functions constexpr may move them into the same direction but making such type traits will probably work better in general.

                  – Scheff
                  Nov 21 '18 at 6:47



















                • I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.

                  – Lapys
                  Nov 21 '18 at 6:37






                • 1





                  @Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?

                  – StoryTeller
                  Nov 21 '18 at 6:40













                • Ah, I see. Thanks.

                  – Lapys
                  Nov 21 '18 at 6:42








                • 1





                  @Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functions constexpr may move them into the same direction but making such type traits will probably work better in general.

                  – Scheff
                  Nov 21 '18 at 6:47

















                I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.

                – Lapys
                Nov 21 '18 at 6:37





                I appreciate the answer, but I would still like to understand how it has an edge syntactically over plain function overloading.

                – Lapys
                Nov 21 '18 at 6:37




                1




                1





                @Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?

                – StoryTeller
                Nov 21 '18 at 6:40







                @Lapys - You mean what edge putting the relevant information in a table and abstracting the logic has over repeating the same exact logic for different data?

                – StoryTeller
                Nov 21 '18 at 6:40















                Ah, I see. Thanks.

                – Lapys
                Nov 21 '18 at 6:42







                Ah, I see. Thanks.

                – Lapys
                Nov 21 '18 at 6:42






                1




                1





                @Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functions constexpr may move them into the same direction but making such type traits will probably work better in general.

                – Scheff
                Nov 21 '18 at 6:47





                @Lapys Providing such info as type instead of as function, allows to use it in compile time evaluation (vs. runtime evaluation). I.e. the compiler can use this info to make type checks or even to compile code conditionally. So, the range of possible usages is larger. Making the functions constexpr may move them into the same direction but making such type traits will probably work better in general.

                – Scheff
                Nov 21 '18 at 6:47











                2














                Might



                #include <type_traits>
                #include <string>

                template<typename T>
                bool is_string(T)
                {
                return std::is_constructible<std::string, T>::value;
                }


                be enough?






                share|improve this answer




























                  2














                  Might



                  #include <type_traits>
                  #include <string>

                  template<typename T>
                  bool is_string(T)
                  {
                  return std::is_constructible<std::string, T>::value;
                  }


                  be enough?






                  share|improve this answer


























                    2












                    2








                    2







                    Might



                    #include <type_traits>
                    #include <string>

                    template<typename T>
                    bool is_string(T)
                    {
                    return std::is_constructible<std::string, T>::value;
                    }


                    be enough?






                    share|improve this answer













                    Might



                    #include <type_traits>
                    #include <string>

                    template<typename T>
                    bool is_string(T)
                    {
                    return std::is_constructible<std::string, T>::value;
                    }


                    be enough?







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 21 '18 at 6:37









                    SwordfishSwordfish

                    9,42311436




                    9,42311436























                        1














                        You might directly do:



                        template <typename T>
                        constexpr bool isString()
                        {
                        return std::is_same<T, const char*>::value
                        || std::is_same<T, char*>::value
                        || std::is_same<T, std::string>::value;
                        }


                        then if you have to set of overloads, you might use SFINAE:



                        template <typename T>
                        std::enable_if_t<isString<T>()> foo(/**/) { /*..*/}

                        template <typename T>
                        std::enable_if_t<!isString<T>()> foo(/**/) { /*..*/}


                        or if constexpr (c++17):



                        template <typename T>
                        void foo(/**/)
                        {
                        if constexpr (isString<T>()) {
                        /*..*/
                        } else {
                        /*..*/
                        }
                        }





                        share|improve this answer




























                          1














                          You might directly do:



                          template <typename T>
                          constexpr bool isString()
                          {
                          return std::is_same<T, const char*>::value
                          || std::is_same<T, char*>::value
                          || std::is_same<T, std::string>::value;
                          }


                          then if you have to set of overloads, you might use SFINAE:



                          template <typename T>
                          std::enable_if_t<isString<T>()> foo(/**/) { /*..*/}

                          template <typename T>
                          std::enable_if_t<!isString<T>()> foo(/**/) { /*..*/}


                          or if constexpr (c++17):



                          template <typename T>
                          void foo(/**/)
                          {
                          if constexpr (isString<T>()) {
                          /*..*/
                          } else {
                          /*..*/
                          }
                          }





                          share|improve this answer


























                            1












                            1








                            1







                            You might directly do:



                            template <typename T>
                            constexpr bool isString()
                            {
                            return std::is_same<T, const char*>::value
                            || std::is_same<T, char*>::value
                            || std::is_same<T, std::string>::value;
                            }


                            then if you have to set of overloads, you might use SFINAE:



                            template <typename T>
                            std::enable_if_t<isString<T>()> foo(/**/) { /*..*/}

                            template <typename T>
                            std::enable_if_t<!isString<T>()> foo(/**/) { /*..*/}


                            or if constexpr (c++17):



                            template <typename T>
                            void foo(/**/)
                            {
                            if constexpr (isString<T>()) {
                            /*..*/
                            } else {
                            /*..*/
                            }
                            }





                            share|improve this answer













                            You might directly do:



                            template <typename T>
                            constexpr bool isString()
                            {
                            return std::is_same<T, const char*>::value
                            || std::is_same<T, char*>::value
                            || std::is_same<T, std::string>::value;
                            }


                            then if you have to set of overloads, you might use SFINAE:



                            template <typename T>
                            std::enable_if_t<isString<T>()> foo(/**/) { /*..*/}

                            template <typename T>
                            std::enable_if_t<!isString<T>()> foo(/**/) { /*..*/}


                            or if constexpr (c++17):



                            template <typename T>
                            void foo(/**/)
                            {
                            if constexpr (isString<T>()) {
                            /*..*/
                            } else {
                            /*..*/
                            }
                            }






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 21 '18 at 9:48









                            Jarod42Jarod42

                            116k12102182




                            116k12102182






























                                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%2f53406038%2fshorthand-for-overloading-multiple-functions%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

                                MongoDB - Not Authorized To Execute Command

                                How to fix TextFormField cause rebuild widget in Flutter

                                Npm cannot find a required file even through it is in the searched directory