Static if

Discussion in 'C++' started by markus, May 26, 2014.

  1. markus

    markus Guest

    I'm trying to work around the lack of static if. The use case is
    something like:

    ---------------------------------------------------------------
    struct A {
    static const bool is_a = true;
    int v1;
    int v2;
    int v3;
    };

    struct B {
    static const bool is_a = false;
    int v1;
    static int v2; // dummy to make things compile
    int v3;
    };

    template<class AorB>
    class MyClass {
    public:
    void doSomething(AorB p) {
    ++p.v1;
    if(AorB::is_a) ++p.v2;
    ++p.v3;
    }
    };

    int main() {
    MyClass<A> a; a.doSomething(A());
    MyClass<B> b; b.doSomething(B());
    }
    ---------------------------------------------------------------

    Is there some better way to do that (C++11 is fine)?

    Constraints:
    - The memory layout must be exactly as above. Reordering of
    fields or additional padding is a no-no.
    - There can't be any run-time overhead.
    - A/B must be trivially copyable.
    - doSomething can't be decomposed into multiple or separate
    functions. The vast majority of code is the same for the A or
    B case and adding some utility function for handling v2 is
    very messy.
     
    markus, May 26, 2014
    #1
    1. Advertisements

  2. Am 26.05.2014 12:38, schrieb markus:
    > I'm trying to work around the lack of static if. The use case is
    > something like:
    >
    > ---------------------------------------------------------------
    > struct A {
    > static const bool is_a = true;
    > int v1;
    > int v2;
    > int v3;
    > };
    >
    > struct B {
    > static const bool is_a = false;
    > int v1;
    > static int v2; // dummy to make things compile
    > int v3;
    > };
    >
    > template<class AorB>
    > class MyClass {
    > public:
    > void doSomething(AorB p) {
    > ++p.v1;
    > if(AorB::is_a) ++p.v2;
    > ++p.v3;
    > }
    > };
    >
    > int main() {
    > MyClass<A> a; a.doSomething(A());
    > MyClass<B> b; b.doSomething(B());
    > }
    > ---------------------------------------------------------------
    >
    > Is there some better way to do that (C++11 is fine)?


    Add an inline member function called "increment" that increments v2 for
    A and does nothing for B. As long as it is not virtual (which you do not
    need) A and B remain trivially copyable and there is no call-overhead
    due to in-lining.

    Greetings,
    Thomas
     
    Thomas Richter, May 26, 2014
    #2
    1. Advertisements

  3. markus

    David Brown Guest

    On 26/05/14 12:38, markus wrote:
    > I'm trying to work around the lack of static if. The use case is
    > something like:
    >
    > ---------------------------------------------------------------
    > struct A {
    > static const bool is_a = true;
    > int v1;
    > int v2;
    > int v3;
    > };
    >
    > struct B {
    > static const bool is_a = false;
    > int v1;
    > static int v2; // dummy to make things compile
    > int v3;
    > };
    >
    > template<class AorB>
    > class MyClass {
    > public:
    > void doSomething(AorB p) {
    > ++p.v1;
    > if(AorB::is_a) ++p.v2;
    > ++p.v3;
    > }
    > };
    >
    > int main() {
    > MyClass<A> a; a.doSomething(A());
    > MyClass<B> b; b.doSomething(B());
    > }
    > ---------------------------------------------------------------
    >
    > Is there some better way to do that (C++11 is fine)?
    >
    > Constraints:
    > - The memory layout must be exactly as above. Reordering of
    > fields or additional padding is a no-no.
    > - There can't be any run-time overhead.
    > - A/B must be trivially copyable.
    > - doSomething can't be decomposed into multiple or separate
    > functions. The vast majority of code is the same for the A or
    > B case and adding some utility function for handling v2 is
    > very messy.


    What is wrong with doing it this way? The compiler will see the "if
    (AorB::is_a)" and evaluate it at compile time, then remove the dead code
    in the B case. You should not be getting any run-time overhead with the
    code above.
     
    David Brown, May 26, 2014
    #3
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.