C++ 为什么boost::sort会推断常量范围&;输入类型?

C++ 为什么boost::sort会推断常量范围&;输入类型?,c++,c++11,boost,C++,C++11,Boost,当我尝试将嵌套的boost::acculate算法的结果(其中结果是std::vector)传递到boost::sort)中时,编译器推断出boost::sort的输入是const std::vector&,即使它正确地将boost::acculate的返回类型推断为std::vector。为什么呢?下面的代码没有编译,抱怨operator=没有为result定义 #include <boost/range/algorithm/find_if.hpp> #include <bo

当我尝试将嵌套的
boost::acculate
算法的结果(其中结果是
std::vector
)传递到
boost::sort
)中时,编译器推断出
boost::sort
的输入是
const std::vector&
,即使它正确地将
boost::acculate
的返回类型推断为
std::vector
。为什么呢?下面的代码没有编译,抱怨
operator=
没有为
result
定义

#include <boost/range/algorithm/find_if.hpp>
#include <boost/range/algorithm_ext/copy_n.hpp>
#include <boost/range/algorithm/sort.hpp>
#include <boost/range/numeric.hpp>

#include <iomanip>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>

struct resultT
{
    std::string name;
    double quantity;
};

auto operator<(const resultT& lhs, const resultT& rhs) -> bool
{
    return std::tie(lhs.quantity, lhs.name)
        < std::tie(rhs.quantity, rhs.name);
}

auto operator>(const resultT& lhs, const resultT& rhs) -> bool
{
    return rhs < lhs;
}

auto operator<<(std::ostream& os, const resultT& row) -> std::ostream&
{
    os << row.name << '\t' << std::setprecision(4) << std::fixed << row.quantity;
    return os;
}

template<typename T>
auto calculate(const T& in) -> double
{
    //a stand-in for real operations on T--not important to the example
    return in.second;
}

using resultContainer = std::vector<resultT>;

template<typename QuantityT>
auto add(resultContainer& accumulated, const QuantityT& next) -> resultContainer&
{
    auto accumulated_itr{boost::find_if(accumulated, [&next](const resultT& in) -> bool
    {
        return in.name == next.second.first;
    })};

    if (accumulated_itr == std::end(accumulated))
    {
        accumulated.emplace_back(resultT{next.second.first, calculate(next.second)});
    }
    else
    {
        accumulated_itr->quantity += calculate(next.second);
    }

    return accumulated;
}

auto main() -> int
{
    using InnerT = std::pair<int, std::pair<std::string, int>>;
    using OuterT = std::pair<char, std::pair<std::string, int>>;
    auto addInnerOne{[](resultContainer& accumulated, const InnerT& next) { return add<InnerT>(accumulated, next); }};
    auto addOuterOne{[](resultContainer& accumulated, const OuterT& next) { return add<OuterT>(accumulated, next); }};

    auto InnerOne{std::unordered_multimap<int, std::pair<std::string, int>>
    {
        {0, {"hi", 1}}
        , {1, {"ho", 5}}
        , {2, {"hi", 7}}
        , {3, {"ho", 7}}
        , {4, {"hey", 9}}
        , {5, {"fiddle", 11}}
        , {6, {"hey", 11}}
        , {7, {"ho", 3}}
    }};
    auto OuterOne{std::unordered_map<char, std::pair<std::string, int>>
    {
        {'A', {"hi", 1}}
        , {'B', {"ho", 5}}
        , {'C', {"hi", 7}}
        , {'D', {"ho", 7}}
        , {'E', {"hey", 9}}
        , {'F', {"diddle", 21}}
        , {'G', {"hey", 5}}
        , {'H', {"ho", 3}}
    }};

    boost::copy_n(
        boost::sort(
            boost::accumulate(OuterOne
                              , boost::accumulate(InnerOne
                                                  , resultContainer{}
                                                  , addInnerOne)
                              , addOuterOne)
                    , std::greater<resultT>())
        , 5
        , std::ostream_iterator<resultT>(std::cout, "\n"));

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构结果
{
std::字符串名;
双倍数量;
};
自动操作员布尔
{
返回标准::tie(左侧数量、左侧名称)
(常量结果和左侧、常量结果和右侧)->bool
{
返回rhs
template<
    class SinglePassRange,
    class Value,
    class BinaryOperation
    >
Value accumulate(const SinglePassRange& source_rng,
                 Value init,
                 BinaryOperation op);
在这两种情况下,
RandomAccessRange
被推断为
std::vector
,但只有后者可用于调用
排序(累加(…,vector{},…)


通过首先将
boost::acculate
的返回值赋给变量
quant
,涉及此名称的表达式反过来是一个非常量左值,因此它受到所需重载的约束。

因为
quant
是一个左值,而
acculate
的结果是一个PR值。为什么你认为
累计
返回
向量&
?嗯,即使我传入一个空的左值进行累计,而不是像上面那样使用右值?(我试着构造一个空的左值并将其传递进去——没有效果)。我想我假设它将返回一个
向量&
,因为这是我在所有运算符中使用的类型。愚蠢的假设,一个没有IDE中任何类型推断支持的假设。我从问题文本中删除了
&
。“即使我传入一个空的左值进行累加,而不是像上面那样使用右值?”累加总是返回一个PRVALUE。是否仍有修改累加返回类型的方法?也许通过明确指定
Value
的类型作为引用?@caps这似乎不合理,您可以创建一个引用包装器,然后将prvalue转换为左值引用,但这很难看
template<
    class SinglePassRange,
    class Value,
    class BinaryOperation
    >
Value accumulate(const SinglePassRange& source_rng,
                 Value init,
                 BinaryOperation op);
template<class RandomAccessRange>
RandomAccessRange& sort(RandomAccessRange& rng);

template<class RandomAccessRange>
const RandomAccessRange& sort(const RandomAccessRange& rng);