c++templatesspecialization

Specialization of member function from a templated class inside the class body


I have templated class which has a function (myfunc()) which does the same on every case of T except some cases (eg. bool). I have a working solution, based on this question:

template <class T> class opt_arg{
    private: void myfunc(){
     /*Do generic stuff */
    }

/* Can I insert here the bool specialization? */

};

/* The specialization "inserted outside of the class body": */
template<>
 inline void opt_arg<bool>::myfunc(){
    /* Do bool specific stuff*/
 }

As I have mentioned, it is working fine. I am just wondering, that can I insert the function specialization inside the "class body"?


Solution

  • From C++17 you can use if constexpr (which is resolved at compile time) to achieve a similar result:

    template <class T> class opt_arg {
    private: 
        void myfunc() {
            if constexpr (std::same_as<T, bool>) {
                // specialized stuff
            }
            else {
                // generic stuff
            }
        }
    };
    

    Live demo

    As @JeremyRichards commented below, with if constexpr in this case the code in the false branch might not even compile (thanks to the compile time resolve) which can be useful.
    More info about this can be found here: Why does the false branch of "if constexpr" get compiled? (summary: this is true only for if constexpr within a template, and the code should anyway not be ill-formed).

    Note the usage of std::same_as concept which is available from C++20. For C++17, you can use the type trait std::is_same (and the helper std::is_same_v).

    You can add more if constexpr branches for other types if you need (or treat several types in the same branch).

    This way the logic for both cases is in one place, similarly to what you wanted.