【问题标题】:How can I make a macro work on any container?如何使宏在任何容器上工作?
【发布时间】:2017-12-21 14:40:50
【问题描述】:

我有以下一段代码,我在其中使用宏来检查向量中是否存在元素。

#define x.contains(a) x.find(a)!=x.end()
void main(){
     vector<int> v = {1,2,3,4};
     if(v.contains(2))
         cout<<"yes"<<endl;
     else
         cout<<"no"<<endl;
}

但在编译时出现以下错误:

ISO C++11 requires whitespace after the macro name #define x.contains(a) x.find(a)!=x.end()

请告诉我一条出路。 谢谢。

【问题讨论】:

  • “请告诉我一条出路。” 使用模板函数,而不是宏。宏永远不是答案。 (*从不意味着偶尔,但对 99.999% 的用户而言并非如此)
  • 为此使用宏是一个坏主意。写一个合适的函数就行了。
  • 不要写void main()。看看:stackoverflow.com/questions/636829/…
  • 如果你将它定义为 contains(x, a),它可以工作,但永远不会这样
  • 在不相关的说明中,如果您想更通用并允许任何容器,那么您应该真正改用std::find

标签: c++ macros


【解决方案1】:

宏不再是解决方案。

如果你仍然想朝这个方向发展,你需要让你的宏看起来像一个函数而不是一个成员函数,并且还要使用单独的括号来避免与运算符优先级相关的意外影响:

#define contains(x,a) ((x).find(a)!=(x).end())

但是如果你这样做的话,不使用 C++ 模板来代替宏就太可惜了。例如:

template <class T, class U> 
bool contains (const T& x, U a) {
    return x.find(a)!=x.end();
}

模板相对于宏的一个巨大优势是可以定义特化。然后编译器选择最合适的实现。 例如,宏版本和我之前的示例都不能与&lt;list&gt; 一起使用,因为没有find() 成员函数。但是使用模板,您可以定义更专业的版本:

template <class U>
bool contains (const list<U>& x, U a) {
    return std::find(x.begin(), x.end(), a)!=x.end();
}

Online demo

【讨论】:

  • 添加,不使用宏的原因查看这篇文章:stackoverflow.com/questions/14041453/…
  • @Carlos 感谢您提供此附加参考。与此同时,我添加了一个非常具体和具体的论点,如果 OP 想在 list 上使用 contains
猜你喜欢
  • 2021-11-03
  • 1970-01-01
  • 2017-05-21
  • 2022-07-12
  • 2017-11-05
  • 2022-07-17
  • 2021-06-05
  • 1970-01-01
  • 2011-04-15
相关资源
最近更新 更多