VLL
VLL

Reputation: 10165

How to assert at compile time, that a function is member of specific class

I have an interface in which the content of each function is created with a big macro. If a programmer is adding a new function, and forgets to add that function to the interface class, it creates many compile errors which distract from the actual error.

Would it be possible to assert at compile time, that a function that uses this particular macro is a member of specific class? C++03 or Boost features are available.

#define MACRO_OF_THE_DOOM(...) assertion_here(); do_something();

class A {
    void functionA();
    void functionB();
};

// This is valid usage
void A::functionA() {
    MACRO_OF_THE_DOOM(1, 2, 3, 4, 5);
}

// This should give an understandable compile error, which tells
// definition should be A::functionB()
void functionB() {
    MACRO_OF_THE_DOOM(6, 7, 8);
}

Upvotes: 1

Views: 221

Answers (2)

marcinj
marcinj

Reputation: 49986

Would it be possible to assert at compile time, that a function that uses this particular macro is a member of specific class?

If boost is available to you (I understand you cannot use c++11), then I suggest TTI Library. Below is example with comments:

http://coliru.stacked-crooked.com/a/66a5016a1d02117c

#include <iostream>

#include <boost/tti/has_member_function.hpp>
#include <boost/static_assert.hpp>

BOOST_TTI_HAS_MEMBER_FUNCTION(functionA)
BOOST_TTI_HAS_MEMBER_FUNCTION(functionB)

class A {
public: // must be public for tti
    void functionA();
    //void functionB();
};    

int main()
{   
    // prints 1
    std::cout << has_member_function_functionA<
       A, // class type to check
       void,    // function return type
       boost::mpl::vector<> >::value // parameter list
       << std::endl;

    // Below generates no compile error - prints 0
    std::cout << has_member_function_functionB<
       A, // class type to check
       void,    // function return type
       boost::mpl::vector<> >::value // parameter list
       << std::endl;

    // Below static assertion, will fail at compile time    
    BOOST_STATIC_ASSERT(
        (has_member_function_functionB<A,void,boost::mpl::vector<> >::value));

}

I have updated to make it compliant with c++03, unfortunately static assertion without c++11 generates quite criptic message:

main.cpp: In function 'int main()':
main.cpp:32:5: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>'
     BOOST_STATIC_ASSERT(
     ^
main.cpp:32:5: error: template argument 1 is invalid
     BOOST_STATIC_ASSERT(
     ^

Upvotes: 1

bashrc
bashrc

Reputation: 4835

You can use BOOST_STATIC_ASSERT

#define MACRO_OF_THE_DOOM(...)  { assertion_here(); do_something(); }

assertion_here() { BOOST_STATIC_ASSERT(false); }
class A {
    assertion_here() { // no-op }
    void functionA();
    void functionB();
};

There are few caveats around this which could be worked around using type_traits but this solution may suffice for many cases.

Upvotes: 1

Related Questions