Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
705 views
in Technique[技术] by (71.8m points)

c++ - Couldn't deduce template parameter from function parameter's default argument

I'm trying to make a function which finds the minimum element in a range which satisfies a given condition:

#include <functional>
#include <iostream>
#include <vector>

template <typename It, typename Pred, typename Comp>
It minElementWhere(
    It begin,
    It end,
    Pred pred = Pred(),

    // Use less-than as the default comparator.
    Comp comp = std::less<decltype(*std::declval<It>())>()
) {
    It minElement = end;

    for (It it = begin; it != end; ++it) {
        if (!pred(*it)) {
            continue;
        }

        if (comp(*it, *minElement)) {
            minElement = it;
        }
    }

    return minElement;
}

int main() {
    std::vector<double> foo;
    foo.push_back(6);
    foo.push_back(10);
    foo.push_back(-3);
    foo.push_back(7);

    std::cout << *minElementWhere(
        foo.begin(),
        foo.end(),
        [](double val) {
            return val >= 0;
        }
    ) << std::endl;
}

But I get this error:

main.cpp: In function 'int main()':
main.cpp:40:5: error: no matching function for call to 'minElementWhere(std::vector<double>::iterator, std::vector<double>::iterator, main()::__lambda0)'
     ) << std::endl;
     ^
main.cpp:40:5: note: candidate is:
main.cpp:6:4: note: template<class It, class Pred, class Comp> It minElementWhere(It, It, Pred, Comp)
 It minElementWhere(
    ^
main.cpp:6:4: note:   template argument deduction/substitution failed:
main.cpp:40:5: note:   couldn't deduce template parameter 'Comp'
     ) << std::endl;

Comp isn't the return type, so it's not trying to deduce the return type, and it doesn't seem to me like there are ambiguous overloads of Comp (since there can only be one return type of dereferencing an It). Why am I getting this error, and how can I fix it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You're expecting the template parameter Comp to be deduced from the default argument you provided for the corresponding function parameter. However, this is explicitly listed as a non-deduced context, meaning template argument deduction will fail for that template parameter (unless it can be deduced from elsewhere).

From §14.8.2.5/5 [temp.deduct.type]

The non-deduced contexts are:
— ...
— A template parameter used in the parameter type of a function parameter that has a default argument that is being used in the call for which argument deduction is being done.

To have template argument deduction succeed, provide a default argument for the template parameter, instead of the function parameter.

template <typename It, 
          typename Pred, 
          typename Comp = std::less<decltype(*std::declval<It>())>>
It minElementWhere(
    It begin,
    It end,
    Pred pred = Pred(),
    Comp comp = Comp()
) {
...
}

Live demo


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...