Function presence accepts only lvalues ​​constants

I have a function that sorts two vectors with the first of them as an ordering criterion. His signature

template<typename A, typename B>
void sort(A&& X, B&& Y)
{
  ..
}

The problem is that universal links would make senseless cases like

sort(vector<int>{ 2,1,3 }, vector<int>{ 3,1,2 });

where the rvalue will be destroyed afterwards (nonsense).

The job explicitly for lvalue does not work, since

template<typename A, typename B>
void sort(A& X, B& Y) ... // (*)

sort(vector<int>{2,1,3}, vector<int>{3,1,2});

for some reason the above compilation (I thought that only const lvalues ​​are allowed to contact rvalues ​​and extend their lifespan?).

If I add an constlvalue to the link, then the function will no longer be able to modify the vectors and sort them.


My questions:

1) , // (*), r l, const? - int& r = 20; ? ?

2) , lvalues, rvalue temporaries? ( , )

, ++

+4
5

: .

gcc clang , - :

prog.cpp: 'int main()': prog.cpp: 9: 45: error: 'std::vector &' rvalue 'std::vector' sort (vector {2,1,3}, {3,1,2});                                              ^ prog.cpp: 6: 6: note: 1 'void sort (A &, B &) [ A = std::vector; B = std::vector] 'void sort (A & X, B & Y) {}

+7

/Za, :

error C2664: 'void sort<std::vector<int,std::allocator<_Ty>>,std::vector<_Ty,std::allocator<_Ty>>>(A &,B &)' : cannot convert argument 1
from 'std::vector<int,std::allocator<_Ty>>' to 'std::vector<int,std::allocator<_Ty>> &'
        with
        [
            _Ty=int
,            A=std::vector<int,std::allocator<int>>
,            B=std::vector<int,std::allocator<int>>
        ]
        and
        [
            _Ty=int
        ]
        and
        [
            _Ty=int
        ]
        A non-const reference may only be bound to an lvalue

, /Za - <windows.h>, . 2012 "MSVC/Za " Microsoft . , STL Fixes VS 2015, 2, :

/Za /Zc. , VC , , . , STL, .

, , MSVC.


: ++ , " ". , MSVC , .

+2

, .

:

struct sfinae_helper {};
template<bool b>
using sfinae = typename std::enable_if<b, sfinae_helper>::type*;
// sfinae_helper, because standard is dumb: void*s are illegal here

template<class A, class B,
  sfinae<!std::is_const<A>::value&&!std::is_const<B>::value> = nullptr
>
void sort(A& X, B& Y) ... // (*)

sort(vector<int>{2,1,3}, vector<int>{3,1,2});

MSVC2013 .

, A B const X , const X A B.

:

template<typename A, typename B>
void sort(A& X, B& Y) ... // (*)
template<typename A, typename B>
void sort(A&& X, B&& Y) = delete;

, A&, B&. , MSVC , .

+1

X, , Y, , , , . , - , , , .

, , : , .

:

interesting_container A;
// fill A
sort(an_ordering_criterion(), A);

""; , :

vector<int> A, B;
// fill A and B
sort(make_subsequence(A, 1, 10), make_subsequence(B, 5, 14));
+1

delete sort:

#include <iostream>
#include <vector>

#include <cstdlib>

template< typename X, typename Y >
void
sort(X &, Y &)
{
    static_assert(!std::is_const< X >{});
    static_assert(!std::is_const< Y >{});
}

template< typename X, typename Y >
int
sort(X const &, Y &) = delete;

template< typename X, typename Y >
int
sort(X &, Y const &) = delete;

template< typename X, typename Y >
int
sort(X const &, Y const &) = delete;

int
main()
{
    std::vector< int > v{1, 3, 5};
    std::vector< int > const c{2, 4, 6};
    ::sort(v, v); // valid
    { // has been explicitly deleted
        //::sort(v, c); 
        //::sort(c, v);
        //::sort(c, c);
    }
    { // not viable: expects an l-value for 1st argument
        //::sort(std::move(v), v); 
        //::sort(std::move(v), c);
        //::sort(std::move(c), v);
        //::sort(std::move(c), c);
    }
    { // not viable: expects an l-value for 2nd argument
        //::sort(v, std::move(v));
        //::sort(v, std::move(c));
        //::sort(c, std::move(v));
        //::sort(c, std::move(c));
    }
    { // not viable: expects an l-value for 1st or 2nd argument
        //::sort(std::move(v), std::move(v));
        //::sort(std::move(v), std::move(c));
        //::sort(std::move(c), std::move(v));
        //::sort(std::move(c), std::move(c));
    }
    return EXIT_SUCCESS;
}
0

Source: https://habr.com/ru/post/1608523/


All Articles