2016-04-28 8 views
1

Ich habe eine Schnittstelle, in der der Inhalt jeder Funktion mit einem großen Makro erstellt wird. Wenn ein Programmierer eine neue Funktion hinzufügt und vergisst, diese Funktion der Schnittstellenklasse hinzuzufügen, erzeugt er viele Kompilierungsfehler, die von dem tatsächlichen Fehler ablenken.Wie zur Kompilierzeit behaupten, dass eine Funktion Mitglied der spezifischen Klasse ist

Wäre es möglich, zur Kompilierzeit zu behaupten, dass eine Funktion, die dieses bestimmte Makro verwendet, Mitglied einer bestimmten Klasse ist? C++ 03 oder Boost-Funktionen sind verfügbar.

#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); 
} 
+4

Der wirkliche Grund dafür ist, dass Sie vergessen, Ihre Funktionen mit "A ::" zu versehen, wenn Sie sie implementieren? Hast du "-Wall" probiert? –

+0

@BartekBanachewicz Ich denke, statische Assert wäre in diesem Fall besser als "-Wall", weil Kompilierungsfehler vor Compiler-Warnungen angezeigt werden. Mich interessiert auch, ob dies theoretisch mit einem statischen Assert möglich wäre. –

+0

@BartekBanachewicz Außerdem scheint der Compiler, den ich verwende, keine Warnung für diese Art von Problem zu haben. –

Antwort

1

können Sie verwenden 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(); 
}; 

Es gibt nur wenige Einschränkungen, um dieses, das um mit type_traits gearbeitet werden könnte, aber diese Lösung für viele Anwendungsfälle ausreichen.

1

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

Wenn Schub zur Verfügung steht (ich verstehe Sie nicht C++ 11 verwenden), dann schlage ich vor TTI Library. Im Folgenden Beispiel mit Kommentaren ist:

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 aktualisiert haben, um es mit C++ 03 leider statische Behauptung erzeugt ganz CRIPTIC Nachricht ohne C++ 11 konform zu machen:

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(
    ^