我仍然不确定问这个问题是否是一个好主意,因为它以某种方式编码风格"问题(那些本质上是主观的),但我希望它能够客观地转向那种方式 如果事实证明它不是,我很抱歉在这里问。
我想问两个问题:
然而,我不知道你是否喜欢这个代码。如果你愿意,我无法阻止你这么说,如果你这么做我就不会介意,但是我想知道它为什么好或坏了可能有助于将这个问题引向潜在的基于意见的问题的黑暗面(假设它已经,我再次道歉,如果是的话)。
最近,我想写一些特征,其中很多都非常简单。但是,每个都需要某种重复的元编程代码。我最终使用宏来使代码更紧凑,重复性更低,使用如下代码:
#include <type_traits>
//...
template<class...>
struct void_type {
typedef void type;
};
template<class... T>
using void_t = void_type<T...>::type;
#define UNARY_EXPRESSION_TYPE_TRAIT(trait_name, expression, expression_type, \
type_name) \
namespace detail_generated { \
template<class type_name, class = void> \
struct trait_name : std::false_type {}; \
\
template<class type_name> \
struct trait_name<type_name, void_t<decltype(expression)>> : \
std::integral_constant< \
bool, std::is_same<decltype(expression), expression_type>::value \
> {}; \
} \
template<class type_name> \
struct trait_name<type_name> : detail_generated::trait_name<type_name> {};
UNARY_EXPRESSION_TYPE_TRAIT(is_preincrementable,
++std::declval<Incrementable&>(),
Incrementable&, Incrementable)
UNARY_EXPRESSION_TYPE_TRAIT(is_predecrementable,
--std::declval<Decrementable&>(),
Decrementable&, Decrementable)
UNARY_EXPRESSION_TYPE_TRAIT(is_contextually_convertible_to_bool,
!std::declval<T>(), bool, T)
#undef UNARY_EXPRESSION_TYPE_TRAIT
// ...
在这种特殊情况下,它避免重复&#34;样板元编程结构&#34;而且我没有看到很多缺点(大多数缺点都是通过立即使用宏来解决的,而且它的直接定义不明确。) 但是,我通常不会对宏感到满意(我发现它们是混淆的,通常是可替换的),我知道它们通常被认为是坏的或者是邪恶的&#34;。遗憾的是,即使在阅读了以下问题之后,我也无法找到替换它的方法,保留它的理由或避免它的理由:
(那个因为虽然不是很有用但很有趣:)
我对他们的答案不满意,因为他们要么:
我无法客观地判断我的代码,而且我无法找到该宏的任何良好替代品(除了实际执行预处理器的工作以及将宏复制粘贴到我需要的任何地方,不管是哪种罢工我至少同样糟糕)。也许我只是没有看到该宏的明显和致命的缺点,或者我甚至没有完全理解为什么不鼓励使用宏。
编辑:删除了注释中建议的某些名称中的前导下划线(保留此类名称)
答案 0 :(得分:1)
宏的问题在于它们忽略了我们在C ++中使用的漂亮的结构化构造。 OTOH,这让我很好地利用了宏:
我会说“去吧”。