14

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"?

2
  • 1
    If I get it right, I think you can't under timsong-cpp.github.io/cppwp/n4861/temp.expl.spec#5: " may be explicitly specialized for a class specialization that is implicitly instantiated; in this case, the definition of the class template shall precede the explicit specialization for the member of the class template"
    – Oersted
    Commented Feb 25 at 10:53
  • 2
    I feel compelled to amend my previous comment (if it was correct). The impossibility I mentioned would be with a similar syntax. However, functionally, there is indeed the solution proposed by @wohlstad.
    – Oersted
    Commented Feb 25 at 11:43

1 Answer 1

17

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.

2
  • 1
    A couple of things: "if constexpr" was first introduced in C++17, so that is as far back as you can go with that route. Also with if constexpr, it is okay if the code in the branch not taken wouldn't compile which can often be useful. Commented Feb 25 at 21:23
  • @JeremyRichards good points, ediited to add them. Note that the code in the false branch doesn't have to compile only within a template and anyway cannot be ill-formed. But I agree it can still be useful.
    – wohlstad
    Commented Feb 26 at 4:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.