Search code examples
c++c++11templatesvariadic-templatestemplate-templates

Using default template argument


This question is best asked by example. Say I want to declare a std::priority_queue with a comparator function. I could do:

auto cmp_fn = [](const std::string& left, const std::string& right) {
    return right < left;
};

std::priority_queue<std::string, std::vector<std::string>, decltype(cmp_fn)> queue(cmp_fn);

Is there any way to avoid specifying the middle template parameter so that the default is used? Something like

auto cmp_fn = [](const std::string& left, const std::string& right) {
    return right < left;
};

std::priority_queue<std::string, /* use default */, decltype(cmp_fn)> queue(cmp_fn);

Note: This is a simplified example of something more complicated I'm doing. Please don't answer with suggestion of the form: "just use std::greater". My question is about the template arguments.


Solution

  • You can use this:

    template <class T, class Comparator>
    using dcpq = /*default container priority queue*/
        std::priority_queue<T, typename std::priority_queue<T>::container_type, Comparator>;
    

    to be used like

    int main() {
        auto cmp_fn = [](const std::string &left, const std::string &right)
                        { return right < left; };
        dcpq<std::string, decltype(cmp_fn)> queue(cmp_fn);
    }
    

    although directly writing

    std::priority_queue<std::string, typename std::priority_queue<T>::container,
        decltype(cmp_fn)> queue(cmp_fn);
    

    might be easier.