template metaprogramming

Pages: 12
The benefit of a static-if statement is a reduction in the overall amount of code that needs to be written.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
template<typename T>
struct SomeClass
{
    //generic code

    static if(std::is_fundamental<T>::value)
    {
        //...
    }
    else if(std::is_reference<T>::value)
    {
        //...
    }
    else
    {
        //...
    }

    //...

    static if(std::is_function<T>::value)
    {
        //...
    }
};
I have a lot of convoluted template code with SFINAE and specialization that is awful to read and write. The addition of static-if would make it much cleaner. Plus there are some things that could be done with static-if that cannot be done currently with templates due to the intricacies of how it works (or they could just relax some of the arbitrary restrictions on templates).
Last edited on
Oh, you mean a new kind of if. I agree, that would be helpful.
It is not a new kind of if; in essence, metaprogramming is merely the logical evolution of a very old kind of if that every competent C++ programmer had always used.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
namespace old
{
    void foo( int a ) { /* do something for int */ }

    void foo( double a ) { /* do something for double */ }

    template < typename T > void foo( const T& a )
    { /* do something for object that is neither an int nor a double */ }

    template < typename T > void bar( T& a )
    {
        foo(a) ; // compile-time if
        // ....
    }
}

namespace not_as_new_as_it_appears_at_first_sight
{
    template < typename T > typename std::enable_if< std::is_integral<T>::value > foo( const T& a ) 
    { /* do something for object of some integral type */ }

    template < typename T > typename std::enable_if< std::is_floating_point<T>::value > foo( const T& a )
    { /* do something for object of some floating point type */ }

    template < typename T > typename std::enable_if< !std::is_arithmetic<T>::value > foo( const T& a )
    { /* do something for object of some non-arithmetic type */ }

    template < typename T > void bar( T& a )
    {
        foo(a) ; // compile-time if
        // ....
    }

    struct timer
    {
        // compile-time if
        using clock_type = typename std::conditional< std::chrono::high_resolution_clock::is_steady,
                                                      std::chrono::high_resolution_clock,
                                                      std::chrono::steady_clock >::type ;
       // ...

       clock_type clock ;
    };
}
It's new in the sense that LB's example doesn't compile on current compilers.
Because it hasn't been accepted into any standard yet. I am hoping it will make it to C++1z/17

With the example JLBogres provided you have to duplicate the condition for multiple functions and there's no way (that I know of) to do it for types (using-aliases). Not to mention the syntax is a pain and has subtle nuances in many cases.
Last edited on
Topic archived. No new replies allowed.
Pages: 12