使用自定义"bind3rd"函数时模板的 C++ 编译错误

c++ compile error with template when using self-defined "bind3rd" function

本文关键字:C++ 编译 错误 自定义 bind3rd 函数      更新时间:2023-10-16

我想编写一个像"bind1st,bind2nd"这样的函数来支持使用stl sort进行多字段排序。无法使用 std:bind ,因为我的 g++ 版本是 3.4.5

它被称为:

#include <alogritm>
std::sort(begin(), end(), bind3rd(SortCond(), indicate));

我的模板函数是:

#ifndef  __INCLUDE_TRIPLE_FUNCTION_H_
#define  __INCLUDE_TRIPLE_FUNCTION_H_
#define TRIPLE_ARG(Operation, Type) Operation::Type
// Define the triple_function prototype
template<class Arg1, class Arg2, class Arg3, class Result>
struct triple_function
{
    // Define the argument type alias
    typedef Arg1 first_argument_type;
    typedef Arg2 second_argument_type;
    typedef Arg3 third_argument_type;
    typedef Result result_type;
};
template <class Operation>
class binder3rd : public binary_function<typename TRIPLE_ARG(Operation, first_argument_type),
    typename TRIPLE_ARG(Operation, second_argument_type), typename TRIPLE_ARG(Operation, result_type)>
{
protected:
    Operation m_op;
    typename Operation::third_argument_type value;
public:
    binder3rd(const Operation& x, const typename Operation::third_argument_type y):m_op(x), value(y){}
    // Convert this function to binary_function using the third argment
    typename Operation::result_type operator()(const typename Operation::first_argument_type& x, const typename Operation::second_argument_type& y) const
    {
        return m_op(x, y, value);
    }
};
// bind3rd function implementation
template<class Operation, class Arg>
inline binder3rd<Operation> bind3rd(const Operation& fn, const Arg& x)
{
    return binder3rd<Operation>(fn, x);
}
#endif  //__INCLUDE/TRIPLE_FUNCTION_H_
/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */

我的测试 cpp 文件是:

#include <algorithm>
#include <cstdlib>
#include "triple_function.h"
using namespace std;
class TestClass{
public:
    int arr[16];
    TestClass() {
        for (int i = 0; i < 16; ++i) {
            arr[i] = rand() % 100;
        }
    }
};
// sort by which fields
class Indicate {
public:
    int ind[16];
};

struct SortA : public triple_function < TestClass, TestClass, const Indicate, bool > 
{
    bool operator () (const TestClass& a, const TestClass& b, 
            const Indicate& indicate) const 
    {
        for (int i = 0; i < 16; ++i) {
            int pos = indicate.ind[i];
            if (a.arr[pos] == b.arr[pos]) {
                continue ;
            }
            return a.arr[pos] < b.arr[pos];
        }
        return false;
    }
};

int main() {
    TestClass a[10];
    Indicate ind;
    for(int i = 0; i < 16; ++i) {
        ind.ind[i] = i;
    }
    sort(a, a+10, bind3rd(SortA(), ind));
    // bind3rd(SortA, ind);
}

使用 g++ 进行编译时,我收到以下编译错误:我的代码有什么问题?

In file included from test.cpp:19:
triple_function.h:32: error: expected template-name before '<' token
triple_function.h:32: error: expected `{' before '<' token
triple_function.h:32: error: expected unqualified-id before '<' token
test.cpp: In function `int main()':
test.cpp:62: error: invalid use of undefined type `class binder3rd<SortA>'
triple_function.h:32: error: declaration of `class binder3rd<SortA>'
triple_function.h: In function `binder3rd<Operation> bind3rd(const Operation&, const Arg&) [with Operation = SortA, Arg = Indicate]':
test.cpp:62:   instantiated from here
triple_function.h:52: error: return type `class binder3rd<SortA>' is incomplete
triple_function.h:53: error: invalid use of undefined type `class binder3rd<SortA>'
triple_function.h:32: error: declaration of `class binder3rd<SortA>'
编译器

正在绊倒您的binary_function基类。如果您的意思是 std::binary_function ,则#include <functional>std::前缀。当然,由于您实际上并没有定义二进制函数,因此我不确定基类是否真的合适......

正如其他人所说,如果您可以使用C++11,std::bind是解决此问题的更好方法。

改用std::bind,你可以这样做,例如:

#include <functional>
...
bool my_compare(const TestClass& a, const TestClass& b, 
                const Indicate& indicate)
{
    ...
}
int main()
{
    ...
    using namespace std::placeholders;
    std::sort(a, a+10, std::bind(my_compare, _1, _2, ind));
}