سؤال

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <algorithm>
#include <ctime>
#include <iterator>
#include <string>
#include <numeric>

template <typename BinaryFunction, typename UnaryFunction1, typename UnaryFunction2>
struct compose2 {
    compose2(BinaryFunction binFunc, UnaryFunction1 unFunc1, UnaryFunction2 unFunc2)
        : m_binFunc(binFunc)
        , m_unFunc1(unFunc1)
        , m_unFunc2(unFunc2) 
    {}
    typedef typename BinaryFunction::return_type return_type;
    typedef typename UnaryFunction1::argument_type argument_type;
    return_type operator()(argument_type arg) {
        return m_binFunc(m_unFunc1(arg), m_unFunc2(arg));
    }

    BinaryFunction m_binFunc;
    UnaryFunction1 m_unFunc1;
    UnaryFunction2 m_unFunc2;
};

int main() {
    std::vector<int> v;
    v.push_back(1);
    v.push_back(75);
    v.push_back(10);
    v.push_back(65);
    v.push_back(15);
    v.push_back(78);
    v.push_back(14);
    v.push_back(19);
    int x = 10, y = 20;

    std::vector<int>::iterator it = std::find_if(v.begin(), v.end(), 
                    compose2(
                        std::logical_and<bool>(),
                        std::bind1st(std::less<int>(), x), 
                        std::bind1st(std::greater<int>(), y)
                    ));

    std::cout << (it - v.begin()) << std::endl;
}

I have tried to implement compose2 adaptor but this doesn't compile. I am getting main.cpp:43:29: error: missing template arguments before ‘(’ token and don’t know what template arguments I should pass. Why it doesn't detect the types.

I know that this is implemented in boost or other library or in new c++11 standard. But I only want to know why does my implementation fail. Thanks.

هل كانت مفيدة؟

المحلول

The compiler can only deduce template arguments for function templates, not class templates. That leaves you with a few choices: the most obvious (but often least convenient) is to specify the template parameters when you instantiate your compose2.

Marginally less obvious, but often more convenient is to create a function template that deduces the parameters, and creates a compose2 object using the deduced types:

template<class BinaryFunction, class UnaryFunction1, class UnaryFunction2>
compose2<BinaryFunction, UnaryFunction1, UnaryFunction2>
make_compose2(BinaryFunction binFunc, UnaryFunction1 unFunc1, UnaryFunction2 unFunc2) {
        return compose2_t<BinaryFunction, UnaryFunction2, UnaryFunction2>
            (binFunc, unFunc1, unFunc2);
}

Then the client code will use make_compose2 instead of compose2, and the template parameters can/will be deduced from the types of the passed parameters.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top