简体   繁体   English

为什么 std::tie 不适用于 const 类方法?

[英]Why doesn't std::tie work with const class methods?

#include <string>
#include <tuple>
#include <stdexcept>
using namespace std;

class Date
{
    public:
        Date() {};
    Date(int new_year, int new_month, int new_day)
    {
        year = new_year;

        if ((new_month < 1) || (new_month > 12))
        {
            throw runtime_error("Month value is invalid: " + to_string(new_month));
        }
        month = new_month;

        if ((new_day < 1) || (new_day > 31))
        {
            throw runtime_error("Day value is invalid: " + to_string(new_day));
        }
        day = new_day;
    }

    int GetYear() const
    {
        return year;
    }

    int GetMonth() const
    {
        return month;
    }

    int GetDay() const
    {
        return day;
    }

    private:
        int year;
    int month;
    int day;
};

bool operator < (const Date &lhs, const Date &rhs)
{
    auto lhs = tie(lhs.GetYear(), lhs.GetMonth(), lhs.GetDay());
    auto rhs = tie(rhs.GetYear(), rhs.GetMonth(), rhs.GetDay());

    return lhs < rhs;
}

I'm trying to create a class for storing the date (year, month, day).我正在尝试创建一个用于存储日期(年、月、日)的类。 In order to use this class in a map, I want to overload the comparison operator.为了在地图中使用这个类,我想重载比较运算符。 Unfortunately, the code above does not work.不幸的是,上面的代码不起作用。 The compiler gives me an error编译器给我一个错误

error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'|

The error apparently occurs in tie function.错误显然发生在tie函数中。 Once I change it to make_tuple everything compiles and works.一旦我将其更改为make_tuple一切都会编译并运行。 I also checked that if I declared variables year , month and day as public I could write something like我还检查了如果我将变量year , monthday为 public 我可以写类似的东西

auto lhs = tie(lhs.year, lhs.month, lhs.day);

and this would also work.这也行。

I don't understand why.我不明白为什么。 Does anyone have ideas?有没有人有想法?

Your member functions return copy of the members(aka temprory rvalue ), and std::tie has argument list, which try to bind by non-cost lvalue ref .您的成员函数返回成员的副本(又名临时rvalue ),并且std::tie具有参数列表,它尝试通过非成本左值 ref进行绑定。

template< class... Types >
constexpr std::tuple<Types&...> tie( Types&... args ) noexcept;
//                                  ^^^^^^^^^^^^^^^^

This is simply not possible as per standard , hence the error! 根据标准,这根本不可能,因此出现错误!


The std::make_tuple on the other hand has forwarding reference .另一方面, std::make_tuple具有forwarding reference Therefore, no issues.因此,没有问题。

template< class... Types >
std::tuple<VTypes...> make_tuple( Types&&... args );
//                               ^^^^^^^^^^^^^^^^

When the members are public, they became lvalues.当成员是 public 时,它们就变成了左值。


I would suggest, make the operator< friend of the class instead.我建议,让operator<成为班级的朋友。

class Date 
{
public:
  // .... other code
  friend bool operator<(const Date& lhs, const Date& rhs) noexcept
  {
    return std::tie(lhs.year, lhs.month, lhs.day) < std::tie(rhs.year, rhs.month, rhs.day);
  }

private:
  int year;
  int month;
  int day;
};

The entire purpose of std::tie is to create a tuple of lvalue references. std::tie的全部目的是创建一个左值引用的元组。 Your member functions return int which aren't lvalues, and so you get an error.您的成员函数返回不是左值的int ,因此您会收到错误消息。

Making the member variables public and using them directly as arguments to tie works because variables are lvalues.公开成员变量并直接使用它们作为tie参数是有效的,因为变量是左值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么const_cast不能处理std :: function的参数? - Why doesn't const_cast work on arguments to std::function? 为什么 std::remove_const 不删除 const 限定符? - Why doesn't std::remove_const remove const qualifier? 为什么不:: boost :: tie与BOOST_FOREACH一起工作? - Why doesn't ::boost::tie work with BOOST_FOREACH? 为什么不`const int ci = 2; std :: forward <int>(ci);`工作以及如何修复/解决它? - Why doesn't `const int ci = 2; std::forward<int>(ci);` work and how to fix / workaround it? 为什么std :: sort不能在std :: list上运行? - Why doesn't std::sort doesn't work on std::list? 为什么每个类都有隐私,但 const 不适用于相同 class 的对象? - Why is privacy on a per-class basis but const doesn't work across objects of the same class? 为什么std :: uppercase不能用于字符串? - Why std::uppercase doesn't work with strings? 为什么std :: function在这种情况下不起作用? - Why doesn't std::function work in this situation? 为什么std :: swap无法在std :: aligned_union上工作 - Why doesn't std::swap work on std::aligned_union 为什么 std::stringstream 不能与 std::string_view 一起使用? - Why doesn't std::stringstream work with std::string_view?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM