gcc (mac/linux) 错误,VisualStudio 编译正常时调用没有匹配的函数

Posted

技术标签:

【中文标题】gcc (mac/linux) 错误,VisualStudio 编译正常时调用没有匹配的函数【英文标题】:gcc (mac/linux) error no matching function for call while VisualStudio compiles ok 【发布时间】:2014-03-21 12:11:05 【问题描述】:

我遇到了跨平台编译的问题。 下面的代码可以在 Win、Mac 和 Linux 上编译(程序是基于 Qt 的),但是为了让它在 Mac 和 Linux 上编译,我必须定义 if/else。

Windows 编译器 (VS2010) 找到定义,但 Mac (gcc4.2) 和 Linux (Ubuntu12LTS) 找不到...

有什么想法吗?也许我错过了一些技术术语来搜索这个? 我希望能够使用“table->setMark(i,MyObj());”适用于所有系统,因为它似乎没有任何特定于平台的代码。

///// .h
   void setMark(int row, MyObj& mark) 
       value(row).setMark(mark); 
   const MyObj& getMark(int row) const
       return value(row).getMark(); 
/////


///// .cpp
   MyObj obj;
   bool ret = false, ifhandled = false;
   m_root_command.evaluate(obj,ret,ifhandled);

   if (m_marked) 
      Table *table = m_thisobj.getTable();
      for (int i = 0; i < table->getRowCount(); i++) 
#if defined(_WIN32)
         // this works in windows, but fails to compile
         // on other platforms with error below
         table->setMark(i,MyObj());
#else
         // I want to get rid of this workaround
         // and use the above code for all platforms
         MyObj objTmp = MyObj();
         table->setMark(i,objTmp);
#endif
      
      m_marked = false;
   
/////

///// Error
program.cpp: In member function 'MyObj Program::evaluate()':
program.cpp:264:36: error: no matching function for call to 'Table::setMark(int&, MyObj)'
program.cpp:264:36: note: candidate is:
table.h:326:9: note: void Table::setMark(int, MyObj&)
table.h:326:9: note:   no known conversion for argument 2 from 'MyObj' to 'MyObj&'
make: *** [program.o] Error 1
/////

【问题讨论】:

【参考方案1】:

您不能将临时对象绑定到非常量引用。要使用table-&gt;setMark(i,MyObj());,您需要更改声明

void setMark(int row, MyObj& mark)

进入

void setMark(int row, const MyObj& mark)

对于函数委托给的setMark 也是如此。

编辑:它在 VS 中工作的事实显然是 known bug/feature

【讨论】:

我不明白的是,在 Windows 以外的操作系统上编译的代码不是使用临时变量,而是使用局部变量。在这种情况下,它应该能够作为非常量参数正确传递给该函数,不是吗? 这需要使用水晶球,因为 OP 的问题似乎有点模棱两可。他想摆脱宏并在所有平台上将其替换为table-&gt;setMark(i,MyObj());。并且该假设代码无法编译该错误。所以,我猜当前显示的代码实际上编译时没有错误。 我已经更改了声明,但我再次收到错误: void setMark(int row, const MyObj& mark) value(row).setMark(mark); // 在成员函数 'void Table::setMark(int, const MyObj&)': 错误: no matching function for call to 'Table::setMark(const MyObj&)' note: Candidate is: note: void Table::setMark (MyObj&) 注意:没有已知的参数 1 从 'const MyObj' 到 'MyObj&' 的转换 您是否忘记更改void setMark(int row, const MyObj&amp; mark) 委托给的函数的声明?该函数的 ref 参数也必须是 const,因为您不能将 const ref 绑定到非 const ref。 我也不会说英语。我的意思是在void setMark(int row, const MyObj&amp; mark) 内部你调用value(row).setMark(mark);。根据新错误,其他函数期望参数是非常量。但是,由于您正确地将引用更改为 const,它不能再绑定到该参数。因此,您还必须更改该其他函数的声明 (void Table::setMark(MyObj&amp;) -> void Table::setMark(const MyObj&amp;))。通常,您应该始终将所有引用声明为 const,除非您打算修改引用的对象。【参考方案2】:

据我所知,问题在于#if 子句。

#if defined(_WIN32)
     table->setMark(i,MyObj());
#else

setMark 代码仅在 Windows 上执行,因为这是唯一的 #if defined(_WIN32) 子句为真的地方。如果您删除 #if 子句,它应该在 Mac OS 和 Linux 上都可以正常工作。

【讨论】:

#else 导致接下来的两行编译。我不知道为什么它是必要的。 是的。我也觉得没有必要。这就是为什么我说要完全删除#if 子句。可能我表达的不是很好。我的想法是删除 #if 子句,它是 else。这样 table->setMark(i,MyObj());将在所有操作系统中每次执行,因此无需创建临时对象。 你可能误解了我的问题! (我不是母语人士,所以请原谅我的写作!)。我知道我的 if 定义,否则的事情。我这样做是为了克服这个问题。问题是为什么:table->setMark(i,MyObj());

以上是关于gcc (mac/linux) 错误,VisualStudio 编译正常时调用没有匹配的函数的主要内容,如果未能解决你的问题,请参考以下文章

C++ 与 gcc 和 Visual Studio 不同的编译错误,“在此上下文中”

单击问题窗口时,在Visual Studio代码上找不到文件错误(使用make,gcc和gcc problemMatcher)

无法理解 C 源代码,它不能在 GCC 中编译,但在 Visual C++ 中

向量查找函数在 Visual Studio 中工作但在 GCC 中不工作

GCC-Visual Studio std::thread 编译器差异

Linux下Visual Studio与gcc的C++兼容性