【问题标题】:c++ compile error in debug but not in releasec ++在调试中编译错误但在发布中没有
【发布时间】:2011-07-18 13:14:27
【问题描述】:

我正在尝试编译一个小型 COM dll(使用 Visual Studio 2008 Pro),它在发布时编译得很好,但是当我尝试在调试中编译它时,我得到一个编译错误:

错误 C2664: 'bool (MyClass &, double)': 无法转换参数 2 从“MyClass”到“double”。

现在这个错误来自我执行此操作的代码中的一行(注意 someValueThatIsADouble 是 double 类型):

std::vector<MyClass>::iterator iter = std::lower_bound(MyVector.begin(), MyVector.end(), someValueThatIsADouble, less);

而less函数是这样定义的:

bool less(MyClass& a, double b);

我不明白为什么会收到此错误,如果此错误有充分的理由,为什么我只能在 Debug(而不是在 Release)中收到它?该 dll 在 Release 中编译时运行良好且不会崩溃。另外,我检查了一下,没有#ifdef DEBUG 或类似的东西可以改变在调试和发布中编译的代码。

编辑:

我自己没有编写代码,这是一个我不太了解的算法,所以我不知道 double 值应该代表什么,我不想去改变里面的逻辑less 函数将 MyClass 而不是 double 作为第二个参数。

class MyClass
{
public :
    MyClass(): _dValue1(0.0),_dValue2(0.0),_dValue3(0.0)
    {
    }
    MyClass(double dValue1, double dValue3, double dValue2): _dValue2(dValue2),_dValue3(dValue3),_dValue1(dValue1)
    {
    }
    ~MyClass() {}
    double getValue1() {return _dValue1;}
    double getValue3() {return _dValue3;}
    double getValue2() {return _dValue2;}
    double _dValue1;
    double _dValue3;
    double _dValue2;

public:

    friend class vector<MyClass>; 


int compare(const MyClass & t1, const MyClass & t2)
{
  if (t1._dValue1 < t2._dValue1)
    return -1;
  else if (t2._dValue1 < t1._dValue1)
    return 1;
  else
    return 0;
}

bool operator> (const MyClass & rhs)
{
    if (  _dValue1 > rhs._dValue1)
        return true;
    else 
        return false;
}

bool operator< (const MyClass & rhs)
{
    if (  _dValue1 < rhs._dValue1)
        return true;
    else 
        return false;
}

};

编辑:

MSalters 的回答表明谓词的调试和发布实现不一样,这使得它在我的情况下在发布而不是在调试中编译(因为代码不是很整洁,不应该使用比较具有 2 种不同类型的功能)。为了能够在调试中使用此代码,我所做的 hack 也是将此行放在任何包含之前(请注意,首选的解决方案应该是具有更好的比较功能,但在我的情况下这是不可能的):

#define _HAS_ITERATOR_DEBUGGING 0 

【问题讨论】:

  • 最好将const 添加到所有常量函数中。

标签: c++ templates compiler-errors debug-mode


【解决方案1】:

错误消息表明您正在使用 MSVC。它的库实现包含对谓词的调试检查。特别是对于偏序谓词(比如你的less),我认为它测试是否Pred(a,b) &amp;&amp; Pred(b,a) == false。显然这在这里行不通。

(谓词的常见错误之一是人们习惯于定义一个顺序,以便a&lt;bb&lt;a。在这种情况下有很多&lt;algorithm&gt;s 会崩溃,这就是为什么现在有一些调试检查以防止此类错误。如果您实际上设法在运行时传递一对错误的 a,b 值,它们仍然只会捕获错误;它们无法在编译时捕获理论错误)

【讨论】:

  • 啊,这很有可能,谢谢!那么有什么方法(可能是 hack)我可以使用提供的代码使其在调试中构建,或者我必须绝对尝试弄清楚如何编写正确的运算符?
  • 这永远不会起作用,因为只要 a == b,它就会评估为 false。但是,也许它会测试类似 Pred(a, b) => !Pred(b, b)
  • STL 错误检查旨在发现像您这样的错误;你可以把它关掉。有关详细信息,请参阅 MSDN。 (调试和发布实际上只是预定义的一组选项。您通常可以对其进行调整。例如,大多数专业人士也为发布构建构建了 .PDB 文件)
  • @ b.buchhold:糟糕,从记忆中弄错了反反身测试。倒。逻辑是你不能同时拥有a&lt;bb&lt;a
  • 在我的例子中,即使我们的 Release 配置构建 PDB 文件,它仍然没有显示我们在 Debug 配置中遇到的所有错误。特别是,仅在 Debug 构建中我们会收到此错误:错误 C4716 [此处的函数模板名称] 必须返回一个值。我非常想学习如何让我们的 Release 配置显示与 Debug 相同的错误。
【解决方案2】:

尝试:

bool less(const MyClass& a, const MyClass& b);

【讨论】:

  • 我应该提到我不想更改 less 函数。刚刚编辑了我的问题。
  • 提供给lower_bound调用的less函数用于比较给定集合的两个项目:由于集合是MyClass的集合,所以less函数必须对MyClass实例进行两个引用。能否提供 MyClass 的声明,可能上面定义了一些特定的操作符。
  • 一开始我也是这么想的,但如果是这样,为什么它在发布模式下编译?
  • 因为在类声明中可能定义了一些强制转换运算符...您应该提供 MyClass 声明。
  • someValueThatIsADouble 是 double 类型?
【解决方案3】:
template<class ForwardIterator, class Type, class BinaryPredicate>
ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const Type& val, BinaryPredicate comp);

first : 一个前向迭代器,指向要搜索的范围内第一个元素的位置。

last : 一个前向迭代器,指向要搜索的范围内最后一个元素之后的位置。

val : 在有序范围内搜索其第一个位置或可能的第一个位置的值。

comp :用户定义的谓词函数对象,定义一个元素小于另一个元素的意义。二元谓词有两个参数,满足时返回真,不满足时返回假。

它在发布时编译,因为在标准的发布实现中禁用了一些检查。但它不应该编译:val 应该是 MyClass 类型而不是 double 类型,然后 less 即使在发布时也不会编译。

【讨论】:

    猜你喜欢
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多