C++嵌套预处理器方向
我正在使用预处理器指令来消除某些模板化运算符定义的膨胀。例如
#define BINARY_VECTOR_RETURN_OPERATOR(optype) \
template <typename T, typename U> \
vector<decltype(T() optype U())> operator optype (const vector<T>& A, const vector<U>& B){ \
vector<decltype(T()*U())> C; \
C.reserve(A.size()); \
typename vector<T>::const_iterator a = A.begin(); \
typename vector<U>::const_iterator b = B.begin(); \
while (a!=A.end()){ \
C.push_back((*a) optype (*b)); \
++a; ++b; \
} \
return C; \
} \
BINARY_VECTOR_RETURN_OPERATOR(*);
BINARY_VECTOR_RETURN_OPERATOR(+);
BINARY_VECTOR_RETURN_OPERATOR(-);
BINARY_VECTOR_RETURN_OPERATOR(%);
,这样效果很好。我现在想做的是有两种操作模式,“调试”和“不调试”,这是我之前通过 #define DEBUG 命令设置的。我想做这样的事情:
#define BINARY_VECTOR_RETURN_OPERATOR(optype) \
template <typename T, typename U> \
vector<decltype(T() optype U())> operator optype (const vector<T>& A, const vector<U>& B){ \
#ifdef DEBUG
uint n = A.size(); \
if (n != B.size()){ \
char buf[BUFFLEN]; \
sprintf(buf, "Size mismatch in operator+(%s,%s), sizes: (%d, %d), crashing!", \
typeid(A).name(), typeid(B).name(), (int) A.size(), (int) B.size()); \
cout << buf << endl; \
throw("Size Mismatch Error"); \
} \
#endif
vector<decltype(T()*U())> C; \
C.reserve(A.size()); \
typename vector<T>::const_iterator a = A.begin(); \
typename vector<U>::const_iterator b = B.begin(); \
while (a!=A.end()){ \
C.push_back((*a) optype (*b)); \
++a; ++b; \
} \
return C; \
} \
但编译器似乎不喜欢那样。我可以使用 #ifdef DEBUG 围绕整个事情重新定义整个 BINARY_VECTOR_RETURN_OPERATOR ,但这不是很优雅。有没有办法按照我的第二个示例的精神来实现代码?
I'm using preprocessor directives to de-bloat some templated operator definitions. E.g.
#define BINARY_VECTOR_RETURN_OPERATOR(optype) \
template <typename T, typename U> \
vector<decltype(T() optype U())> operator optype (const vector<T>& A, const vector<U>& B){ \
vector<decltype(T()*U())> C; \
C.reserve(A.size()); \
typename vector<T>::const_iterator a = A.begin(); \
typename vector<U>::const_iterator b = B.begin(); \
while (a!=A.end()){ \
C.push_back((*a) optype (*b)); \
++a; ++b; \
} \
return C; \
} \
BINARY_VECTOR_RETURN_OPERATOR(*);
BINARY_VECTOR_RETURN_OPERATOR(+);
BINARY_VECTOR_RETURN_OPERATOR(-);
BINARY_VECTOR_RETURN_OPERATOR(%);
So that works fine. What I want to do now is to have two modes of operation, "debug" and "not debug" which I set via a #define DEBUG command earlier. I would like to do something like this:
#define BINARY_VECTOR_RETURN_OPERATOR(optype) \
template <typename T, typename U> \
vector<decltype(T() optype U())> operator optype (const vector<T>& A, const vector<U>& B){ \
#ifdef DEBUG
uint n = A.size(); \
if (n != B.size()){ \
char buf[BUFFLEN]; \
sprintf(buf, "Size mismatch in operator+(%s,%s), sizes: (%d, %d), crashing!", \
typeid(A).name(), typeid(B).name(), (int) A.size(), (int) B.size()); \
cout << buf << endl; \
throw("Size Mismatch Error"); \
} \
#endif
vector<decltype(T()*U())> C; \
C.reserve(A.size()); \
typename vector<T>::const_iterator a = A.begin(); \
typename vector<U>::const_iterator b = B.begin(); \
while (a!=A.end()){ \
C.push_back((*a) optype (*b)); \
++a; ++b; \
} \
return C; \
} \
but the compiler doesn't seem to like that. I could redefine the entire BINARY_VECTOR_RETURN_OPERATOR for each case using #ifdef DEBUG around the whole thing, but that's not very elegant. Is there a way to implement the code in the spirit of my second example?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
#define
中不能包含#if
,但可以在控制的代码中包含
#define
#如果。例如:
如果第一个部分和最后一个部分足够大,您可能需要为它们定义宏。
我并不是说这是一个好主意,但它确实实现了您想要做的事情。
编辑:感谢@okorz001在评论中建议了一个更干净的替代方案:
显然真正的代码会使用更好的名称。
You can't have a
#if
inside a#define
, but you can have a#define
inside the code controlled by a#if
.For example:
If first-part and last-part are big enough, you might want to define macros for them.
I'm not saying this is a good idea, but it does do what you were trying to do.
EDIT: Thanks to @okorz001 for suggesting a cleaner alternative in a comment:
Obviously the real code would use better names.
呃,尽量不要将预处理器用于实际代码。这几乎总是一个非常糟糕的主意。
我尝试将宏重组为模板函数。我对 decltypes 很感兴趣,以至于我拿出了一个特征类来降低函数定义的复杂性!
我真的没有看到完全摆脱宏的方法,只是为了实际运算符重载声明的理智。然而,现在它只是对模板函数operator_impl() 的简单传递,并且您应该能够对调试代码使用#ifdefs。
Ugh, try not to ever use the preprocessor for actual code. It's almost always a really bad idea.
I had a go at restructuring the macro as a template function. I had some fun with the decltypes, so much so that I pulled out a traits class just to reduce the complexity of the function definition!
I don't really see a way of getting rid of the macro completely, just for sanity in the declaration of the actual operator overloads. Now, however, it's just a simple pass-through to the template function operator_impl() and in that you should be able to use #ifdefs for your debug code.
assert
或BOOST_ASSERT
可以完成这项工作吗? (必须承认我以前从未在宏中放置过断言 - 所以在幕后这可能只是重现你的问题)所以,而不是
只写
或
(这里有一些解释性链接 增强断言 和 assert.h)
Does an
assert
orBOOST_ASSERT
do the job? (Got to admit I have never put an assert in a macro before - so behind the scenes this might just be reproducing your problem)So, instead of
just write
or
(Here are some explanitary links for boost assert and assert.h)
可能有一种方法可以按照第二个示例的精神来实现代码。
您可以像这样使用 if() 而不是 #ifdef
请测试并查看这是否有效。
May be there is a way to implement the code in the spirit of your second example.
You can use if() instead of #ifdef like this
Please test and see if this works.