【问题标题】:std::set<string, CustomComparer> cannot use std::find(...) withstd::set<string, CustomComparer> 不能将 std::find(...) 与
【发布时间】:2012-02-06 04:56:09
【问题描述】:

我有以下代码无法编译:

#include <iostream>
#include <set>
#include <functional>
#include <cstring>

using namespace std;

struct StringCompareNoRegister: public binary_function<string, string, bool> {
  bool operator()(string const& lhs, string const& rhs) const {
    return (_stricmp(lhs.c_str(), rhs.c_str()) < 0);
  }
};

int wmain() {
  set<string, StringCompareNoRegister> s;
  s.insert("hello");
  s.insert("STL");
  s.insert("Hello");
  wcout << s.find("Hello")->c_str() << endl;
  wcout << find(s.begin(), s.end(), "Hello")->c_str() << endl;

  return 0;
}

MVCPP v.11 CTP 编译器在使用std::find 的最后一行大喊:

错误 1 ​​错误 C2678: 二进制 '==' : 未找到需要 'const 类型的左操作数 std::basic_string<_elem>' (或者没有可接受的 转换)c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility 3171

为什么我不能编译这段代码? 我做错了什么?

更新:完整的编译器输出

1>----- 构建开始:项目:Test01,配置:调试 Win32 ------ 1> main.cpp 1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(3171): error C2678: binary '==' : no operator found which take 'const 类型的左操作数 std::basic_string<_elem>' (或者没有可接受的 转换) 1> with 1> [ 1> _Elem=char, 1> _Traits=std::char_traits, 1>
_Alloc=std::allocator 1> ] 1> 可以是'内置 C++ operator==(const char [6], const char [6])' 1>
c:\程序文件(x86)\微软视觉工作室 11.0\vc\include\exception(488): 或 'bool std::operator ==(const std::_Exception_ptr &,const std::_Exception_ptr &)' 1>
c:\程序文件(x86)\微软视觉工作室 11.0\vc\include\exception(493): 或 'bool std::operator ==(std::_Null_type,const std::_Exception_ptr &)' 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\exception(499): 或 'bool std::operator ==(const std::_Exception_ptr &,std::_Null_type)' 1> c:\program 文件 (x86)\microsoft visual studio 11.0\vc\include\system_error(419):或
'bool std::operator ==(const std::error_code &,const std::error_condition &)' 1> c:\program files (x86)\microsoft 视觉工作室 11.0\vc\include\system_error(427): 或 'bool std::operator ==(const std::error_condition &,const std::error_code &)' 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\tuple(537): 或 'bool std::operator ==(const std::tuple &,const std::tuple &)' 1> 尝试 匹配参数列表 '(const std::basic_string<_elem>, const char [6])' 1>
与 1> [ 1> _Elem=char, 1>
_Traits=std::char_traits, 1> _Alloc=std::allocator 1> ] 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(3204):见 引用函数模板实例化'_InIt std::_Find,const char[6]>(_InIt,_InIt,_Ty (&))' 正在编译 1> 和 1>
[ 1>
_InIt=std::_Tree_unchecked_const_iterator,std::allocator>>>>, 1>
_Mytree=std::_Tree_val,std::allocator>>>, 1> _Ty=const 字符 [6] 1> ] 1>
d:\docs\programming\test01\test01\main.cpp(39) :参见参考 函数模板实例化'_InIt 标准::查找,常量 char[6]>(_InIt,_InIt,_Ty (&))' 正在编译 1> 和 1>
[ 1>
_InIt=std::_Tree_const_iterator,std::allocator>>>>, 1>
_Mytree=std::_Tree_val,std::allocator>>>, 1> _Ty=const 字符 [6] 1> ] ========== 构建:0 成功,1 失败,0 最新,0 跳过 ==========

【问题讨论】:

  • 奇怪。添加适当的标题等后,这对我来说适用于 GCC。
  • 看来MVCPP11 STL实现(或编译器)有问题...
  • 请贴出完整代码。 string 真的是 std::string 吗?
  • 要尝试的几件事:在std::find 调用中将"Hello" 显式转换为std::string。将你的函子传递给std::find 调用。就目前而言,您的仿函数不会在该调用中使用,它将使用operator==。另外,您能否发布整个构建输出(似乎缺少一些额外的诊断)。
  • @NathanErnst 显式转换没有帮助。 std::find 始终使用 operator==。添加到原始帖子的构建输出。

标签: c++ compiler-errors find set


【解决方案1】:

操作。 确切的答案是我忘记将 &lt;string&gt; 标头添加到包含中。 字符串头包含外部(非成员)std::string 比较函数,如operator==operator&lt; 等。

非常感谢您的回答。

【讨论】:

    【解决方案2】:

    std::find 不以同样的方式使用自定义比较器。您需要重载 == 运算符。

    预期的行为类似于以下内容。参考cplusplus.com

    template<class InputIterator, class T>
      InputIterator find ( InputIterator first, InputIterator last, const T& value )
      {
        for ( ;first!=last; first++) if ( *first==value ) break;
        return first;
      }
    

    因此,如果您使用自定义类型,您会期望得到类似的结果。

    struct Foo {
        Foo(const std::string &s_) : s(s_) {}
        std::string s;
        // used by std::set<Foo, Foo::Less>::find
        struct Less {
            bool operator()(const Foo &lhs, const Foo &rhs) const {
                return lhs.s.compare(rhs.s) < 0;
            }
        };
    };
    
    // used by std::find
    bool operator==(const Foo &lhs, const Foo &rhs) {
        return lhs.s.compare(rhs.s) == 0;
    }
    
    int main(int argc, char ** argv) {
        std::set<Foo, Foo::Less> foos;
        foos.insert(Foo("hello"));
        foos.insert(Foo("STL"));
        foos.insert(Foo("Hello"));
    
        std::cout << foos.find(Foo("Hello"))->s.c_str() << std::endl;
        std::cout << find(foos.begin(), foos.end(), Foo("Hello"))->s << std::endl;
        return 0;
    }   
    

    Linux 刚刚找到 std::string 的运算符,所以我无法测试您的具体行为。您可能需要添加一些包含。

    #include <algorithm>
    #include <string>
    

    否则,定义你自己的很容易。

    bool operator==(const std::string &lhs, const std::string &rhs) {
        return lhs.compare(rhs) == 0;
    }
    

    【讨论】:

    • 谢谢汤姆。请澄清一下:我可以在没有包装代码的情况下以某种方式定义 operator==(string const &amp;lhs, string const &amp;rhs) 吗?
    【解决方案3】:

    嗯,尝试将您的仿函数参数更改为bool operator()(const string &amp; lhs, const string &amp; rhs)。看看有没有帮助。

    【讨论】:

    • string const &amp;paramconst string &amp;param 是相同的。但我听从了你的建议,不幸的是没有任何改变:(
    猜你喜欢
    • 2012-04-23
    • 1970-01-01
    • 2013-11-01
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多