Question

I have a class with a few simple members, and would like to implement a very simple < operator. This is what I started with:

inline bool operator< (const T& lhs, const T& rhs)  { return std::tie(lhs.GetA(), lhs.GetB()) < std::tie(rhs.GetA(), rhs.GetB()); }

Visual studio complains with

Warning 2   warning C4239: nonstandard extension used : 'argument' : conversion from 'A' to 'A &'

It seems the problem is that I am not using members, but rather functions, and am passing a rvalue to a non-const ref. I guess I could save GetA() in a local A, but would rather not.

How do I fix this?

I tried adding

A& GetARef() const { return a; }

which doesn't work as I am trying to return a non-const reference with const.

A& GetARef() { return a; }

This doesn't work, as lhs and rhs are const.

Now I am thinking maybe I should use std::tuple or maybe std::tie( std::cref(lhs.GetA()) ), or maybe a new template

template < typename... T >
std::tuple<const T&...> ctie( const T&... args )
{
    return std::tie( args... );
}

But I can't help but feel that I am over complicating this...

Was it helpful?

Solution

tie makes a tuple of lvalue references, and so doesn't work on temporaries (unless they are const, so that deduction of the tuple type gives const references).

You could use make_tuple to make a tuple of objects, or forward_as_tuple to get either lvalue or rvalue references depending on the arguments' value categories.

Alternatively, you could make your accessor work by returning a const reference to the const member:

A const & GetARef() const { return a; }
  ^^^^^
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top