如何在编译时断言函数是特定 class 的成员
How to assert at compile time, that a function is member of specific class
我有一个界面,其中每个函数的内容都是用一个大宏创建的。如果程序员正在添加一个新函数,而忘记将该函数添加到接口 class,则会产生许多编译错误,从而分散对实际错误的注意力。
是否可以在编译时断言使用此特定宏的函数是特定 class 的成员? C++03 或 Boost 功能可用。
#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);
}
您可以使用 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();
};
关于此的注意事项很少,可以使用 type_traits 解决,但此解决方案可能足以满足许多情况。
Would it be possible to assert at compile time, that a function that uses this particular macro is a member of specific class?
如果您可以使用 boost(我知道您不能使用 c++11),那么我建议 TTI Library。下面是带有注释的示例:
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));
}
我已经更新以使其与 c++03 兼容,不幸的是,没有 c++11 的静态断言会生成非常错误的消息:
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(
^
我有一个界面,其中每个函数的内容都是用一个大宏创建的。如果程序员正在添加一个新函数,而忘记将该函数添加到接口 class,则会产生许多编译错误,从而分散对实际错误的注意力。
是否可以在编译时断言使用此特定宏的函数是特定 class 的成员? C++03 或 Boost 功能可用。
#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);
}
您可以使用 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();
};
关于此的注意事项很少,可以使用 type_traits 解决,但此解决方案可能足以满足许多情况。
Would it be possible to assert at compile time, that a function that uses this particular macro is a member of specific class?
如果您可以使用 boost(我知道您不能使用 c++11),那么我建议 TTI Library。下面是带有注释的示例:
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));
}
我已经更新以使其与 c++03 兼容,不幸的是,没有 c++11 的静态断言会生成非常错误的消息:
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(
^