正如 c++14 所说,仍然需要涉及 c 宏。
我有两个非常常用的宏与 MTP 结合来获得一个编译时间常数,它告诉我一个方法或属性是否存在于一个类中。这只需要函数的名称,该名称不能作为模板的参数给出。所以我在一个 c 宏中准备了它,它“写入”了我的模板,然后可以在 enable_if 子句中使用。
我个人不喜欢“自动吸气剂”中的你的想法,但这只是一个品味问题。
一如既往地在编程中:如果事情有帮助,不是“未定义的行为”,在代码中有很好的记录,并且不能以更严格的方式完成,允许使用 c 宏。对我来说,c 宏是对未集成语言特性的一种“自卫”。
另一个流行的例子是枚举关联文本以进行某种反射或序列化。
捕捉方法存在的例子:
#define DECLARE_HAS_METHOD_FULL_SIGNATURE(NAME) \
template<typename, typename T>\
struct has_method_full_signature_ ## NAME {\
static_assert(\
std::integral_constant<T, false>::value,\
"Second template parameter needs to be of function type.");\
};\
\
\
template<typename C, typename Ret, typename... Args>\
struct has_method_full_signature_ ## NAME <C, Ret(Args...)> {\
template<typename T>\
static constexpr auto check(T*)\
-> typename\
std::is_same<\
decltype( std::declval<T>(). NAME ( std::declval<Args>()... ) ),\
Ret \
>::type; \
\
template<typename>\
static constexpr std::false_type check(...);\
\
using type = decltype(check<C>(0)); \
static constexpr bool value = type::value;\
}
编辑:在此处添加一些示例代码如何使用此 c-macro 内容。
#include <utility>
#include <iostream>
#include "component/mytypes_traits.h"
DECLARE_HAS_METHOD_PARMS_ONLY(funny);
DECLARE_HAS_METHOD_FULL_SIGNATURE(f1);
DECLARE_HAS_METHOD_FULL_SIGNATURE(f2);
DECLARE_HAS_METHOD_FULL_SIGNATURE(f3);
class A { public: void funny() {} };
class B { public: void dummy() {} };
class C
{
public:
int f1(int) { return 1;}
float f2(int,int) {return 2.0;}
int f3() { return 1;}
};
int main()
{
std::cout << has_method_parms_only_funny<A>::value << std::endl;
std::cout << has_method_parms_only_funny<B>::value << std::endl;
std::cout << "--" << std::endl;
std::cout << has_method_full_signature_f1< C, int()>::value << std::endl;
std::cout << has_method_full_signature_f1< C, int(int)>::value << std::endl;
std::cout << has_method_full_signature_f1< C, int(int,int)>::value << std::endl;
std::cout << "--" << std::endl;
std::cout << has_method_full_signature_f2< C, float()>::value << std::endl;
std::cout << has_method_full_signature_f2< C, float(int)>::value << std::endl;
std::cout << has_method_full_signature_f2< C, float(int,int)>::value << std::endl;
std::cout << "--" << std::endl;
std::cout << has_method_full_signature_f3< C, int()>::value << std::endl;
std::cout << has_method_full_signature_f3< C, int(int)>::value << std::endl;
std::cout << has_method_full_signature_f3< C, int(int,int)>::value << std::endl;
std::cout << "--" << std::endl;
}