c++ - 如何在 C++03 中使用自定义谓词调用 std::unique?

标签 c++ lambda functor c++03

我看到了如何在 C++11 中执行此操作的示例:

std::unique(v.begin(), v.end(), [](float l, float r)
{ 
  return std::abs(l - r) < 0.01; 
});

但是,这在 C++03 中对我来说失败了:

error: template argument for 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)' uses local type 'CRayTracer::myFunc()::<lambda(float, float)>'

如何在 C++03 中执行此操作?我认为 Lambda 可能已经存在,仿函数/函数对象也存在,对吗?只是寻找一个简单的解决方案,不需要可扩展 - 它只会在这里使用。

这是一个无法为我编译的代码示例:

#include <iostream>
#include <vector>
#include <algorithm>

int main(){
    std::vector<float> v;
    v.push_back(1.0);
    v.push_back(1.0);
    v.push_back(3.5);
    v.push_back(3.5);

    struct approx_equal
    {
        bool operator()(float l, float r)
        {
            return std::abs(l - r) < 0.01;
        }
    };
    approx_equal f;

    std::unique(v.begin(), v.end(),f);
}

这是它产生的错误:

testUnique.cpp: In function 'int main()':
testUnique.cpp:21:37: error: no matching function for call to 'unique(std::vector<float>::iterator, std::vector<float>::iterator, main()::approx_equal&)'
   21 |     std::unique(v.begin(), v.end(),f);
      |                                     ^
In file included from C:/msys64/mingw64/include/c++/9.2.0/algorithm:62,
                 from testUnique.cpp:3:
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:995:5: note: candidate: 'template<class _FIter> _FIter std::unique(_FIter, _FIter)'
  995 |     unique(_ForwardIterator __first, _ForwardIterator __last)
      |     ^~~~~~
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:995:5: note:   template argument deduction/substitution failed:
testUnique.cpp:21:37: note:   candidate expects 2 arguments, 3 provided
   21 |     std::unique(v.begin(), v.end(),f);
      |                                     ^
In file included from C:/msys64/mingw64/include/c++/9.2.0/algorithm:62,
                 from testUnique.cpp:3:
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:1025:5: note: candidate: 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)'
 1025 |     unique(_ForwardIterator __first, _ForwardIterator __last,
      |     ^~~~~~
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:1025:5: note:   template argument deduction/substitution failed:
testUnique.cpp: In substitution of 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate) [with _FIter = __gnu_cxx::__normal_iterator<float*, std::vector<float> >; _BinaryPredicate = main()::approx_equal]':
testUnique.cpp:21:37:   required from here
testUnique.cpp:21:37: error: template argument for 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)' uses local type 'main()::approx_equal'
   21 |     std::unique(v.begin(), v.end(),f);
      |                                     ^
testUnique.cpp:21:37: error:   trying to instantiate 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)'

这是我的一组标志:

g++ -c -g -O3 -Wp,-D_FORTIFY_SOURCE=2 -m64 -Wshadow -Wall -DMX_COMPAT_32 -fexceptions -fno-omit-frame-pointer -D__WIN32__ -std=c++03 testUnique.cpp -o testUnique.o

最佳答案

I think Lambdas may have already existed,

没有。 C++11 中引入了 Lambda。

... and functors/function objects existed, right?

仿函数只是带有 operator() 的对象,因此它们一直存在(尽管不确定术语“仿函数”何时真正为它们引入)。

对于正式的正确的表达方式我建议你引用其他引用资料,马虎地说这个

auto f = [](float l, float r){ 
  return std::abs(l - r) < 0.01; 
};
f(0.1,0.2);

相当于

struct unnamed {
    bool operator()(float l, float r) {
        return std::abs(l - r) < 0.01; 
    }
};
unnamed f;
f(0.1,0.2);

即您始终可以用手写仿函数类替换 lambda。创建仿函数的实例并传递它而不是 lambda。

完整示例:

#include <iostream>
#include <vector>
#include <algorithm>

struct approx_equal{
    bool operator()(float l, float r) {
        return std::abs(l - r) < 0.01; 
    }
};

int main(){
    std::vector<float> v{1.0, 1.0, 3.5, 3.5 };

    approx_equal f;

    v.erase(std::unique(v.begin(), v.end(),f),v.end());

    // sorry this is c++11, replace with iterator loop to see output pre-c++11
    for (const auto& x : v) std::cout << x << " ";  
}

PS:在 C++03 中,您无法在本地定义仿函数类,然后将其用作模板参数(请注意,您没有显式将其作为模板参数传递,但 unique 必须推导其类型来自您传入的参数)。

关于c++ - 如何在 C++03 中使用自定义谓词调用 std::unique?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58717814/

相关文章:

c++ - 将任何 lambda 存储为 vector 中的公共(public)回调对象

c++ - 是否可以使用 boost::bind 来有效地连接函数?

c++ - 为什么我会遇到段错误?

c++ - 如何在 Ubuntu 16.04 中安装 Eclipse C++ IDE?

c++ - 调用模板函数出错

c++ - Electron (Atom shell) native 代码 : window focus

java - Java 8 中根据条件对列表进行排序

javascript - QML 文件中是否支持 Lambda?

haskell - 为 Fix 编写一个 Eq 实例 (Haskell)

C++ - 从类模板调用方法