Question

Some usual template specialization like this:

template<class T>
class C
{
    void common() { ... }
    void f2 = delete;
};

template<>
class C<int>
{
    void common() { ... }
    void f1() { ... }
};

Could be represented with static_if as:

template<class T>
class C
{
    void common() { ... }

    static_if(std::is_same<T, int>::value)
    {
        void f1( ) { ... }
    }
    else
    {
        void f2( ) = delete;
    }
}

Are these directly competing features? Can template specialization do something static_if cannot? It seems like static_if can do everything template specialization can do, and much much more.

As an aside: I don't really like static_if in this context because it potentially makes what parts of an interface are available to you in any given circumstance non-obvious. Maybe template specialization still provides clearer syntax in some cases.

No correct solution

OTHER TIPS

One thing that static if won't do for you is the "primary" way of using template specializations -- providing generic behaviour in one place and letting the users of your code override (= specialize) it for their specific needs/data types/etc...

No, static_if will not deprecate explicit template specialization. Explicit template specialization is a more powerful feature than static_if, providing many capabilities static_if isn't intended to. static_if is simply a more convenient and readable way to express certain things.

static_if can't do certain things explicit template specialization can, such as changing the the base classes a class inherits from.

struct S {};

template<typename T>
struct T
  static_if(is_same<T,int>::value) { : S }  // ?
{ };

template<typename T>
struct T {};

template<>
struct T<int> : S {};

Ifs are about branching; specialization is about matching. Sometimes one is better than the other.

Here's an example straight from Alexandrescu's Modern C++ Design, Section 11.9, "Multimethods": Suppose you have a complex class hierarchy based on Shape, with virtual and non-virtual inheritance. You'd like to be able to cast among members of the hierarchy as efficiently as possible. Since virtual bases require dynamic_cast, we must allow for that, but we also want to static_cast whenever possible. Solution via cast policy:

template <typename To, typename From> struct ShapeCaster
{ 
    static To & cast(From & x) { return dynamic_cast<To&>(x); }
};

template <> struct ShapeCaster<Triangle, Shape>
{
    static Triangle & cast(Shape & x) { return static_cast<Triangle&>(x); }
};

template <typename To, typename From> To & shape_cast(From & x)
{
    return ShapeCaster<To, From>::cast(x);
}

Now wherever you're moving inside your hierarchy, you can say

To & y = shape_cast<To>::cast(x);

and you get the most efficient cast, and the policy can easily be extended.

Writing this with a series of ifs would be much harder to read.

The static if feature has not even made it into the standard yet. Now, assuming that the related problems are solved and it makes it into the standard, and all compilers support it, the it will be just one more tool in the toolset.

I can imagine different cases where specializations would make the code more readable/maintainable, and in all those cases, specializations would still be the way to go. Note that the greatest advantage of static if is that you can interleave code from different specializations, but that can also be a disadvantage as instead of having multiple simple specializations you might end up with a huge blob of code that gets compiled/ignored conditionally.

I believe yes. static_if is much powerful than template specialization, especially in case when you need to specialize a small part of class, not entire definition. The only case when specialization is better - when your specialized implementation radically differs from main template/other specializations.

Not taking in to account preferences, Yes only and only if it can use another template specialization!

As you all know: std::is_same<T, int>::value Is a template specialization itself!

I am not sure but I think it is implemented like:

template<typename, typename>
struct is_same{
    static constexpr bool value = false;;
};
 template<typename T>
struct is_same<T, T>{
    static constexpr bool value = true;;
};

The real question is, is there finally going to be a method for type/class comparison without template specialization? Maybe only then there will be no need for template specialization!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top