Próbuję zrozumieć std::is_convertible
w C++ 11. Zgodnie z cppreference.com, powinno być ocenione na 1 iff "Jeśli wyimaginowana wartość rinalna typu T
może być użyta w instrukcji return funkcji zwracającej U
". Sformułowanie to nie mówi nic o tym, gdzie można by zadeklarować tę funkcję. Czego można się spodziewać, gdy konstruktor kopii U
jest prywatny? Czego można się spodziewać, gdy T
jest odniesieniem do lwartości?C++ 11 std :: is_convertible zachowanie z prywatnym konstruktorem kopii
przykład rozważyć ten kod:
#include <iostream>
#include <type_traits>
struct Fact_A;
struct A {
friend struct Fact_A;
A() = default;
A(A&&) = delete;
private:
A(const A&) = default;
};
struct Ref_A {
A* _ptr;
Ref_A(A* ptr) : _ptr(ptr) {}
operator A&() { return *_ptr; }
};
struct Fact_A {
static A* make_A(const A& a) { return new A(a); }
static A f(A* a_ptr) { return Ref_A(a_ptr); }
//static A g(A&& a) { return std::move(a); }
};
int main() {
A a1;
A* a2_ptr = Fact_A::make_A(a1);
(void)a2_ptr;
std::cout << std::is_convertible< Ref_A, A >::value << "\n" // => 0
<< std::is_convertible< Ref_A, A& >::value << "\n" // => 1
<< std::is_convertible< A&, A >::value << "\n"; // => 0
}
Używam gcc-4.8.2
lub clang-3.4
(brak różnicy w wyjściu) i skompilować z:
{g++|clang++} -std=c++11 -Wall -Wextra eg.cpp -o eg
Tutaj std::is_convertible< Ref_A, A >
raportów 0
. Można jednak zauważyć, że Fact_A::f
zwraca obiekt typu A
, a wartość rinalna typu Ref_A
jest używana w jego instrukcji return. Problem polega na tym, że konstruktorem kopii A
jest private
, więc tej funkcji nie można umieścić nigdzie indziej. Czy obecne zachowanie jest prawidłowe w odniesieniu do normy?
Drugie pytanie. Jeśli usuniemy private
, dane wyjściowe zmienią się w 1 1 1
. Co oznacza ostatni 1
? Co to jest "wartość rażenia typu A&
"? Czy to jest odwołanie do wartości rvalue? Ponieważ możesz zauważyć, że jawnie usunąłem konstruktor ruchu z A
. W wyniku tego nie mogę zadeklarować Fact_A::g
. Ale nadal, std::is_convertible< A&, A >
raportów 1
.
Dzięki za referencję. Oprócz tego, co powiedziałeś, jest więcej tekstu bezpośrednio pod cytowaną wersją szkicu, która wyraźnie wspomina o problemach z kontekstem. Przyjmę to. Przypuszczam, że pozostaje pytanie, czy norma postępuje słusznie. Nie podoba mi się to, że 'is_convertible' wydaje się niepotrzebnie związany z dostępnością konstruktora' To', który nie ma nic wspólnego z 'From' lub relacją między' From' i 'To'. Mogę sobie wyobrazić sytuacje, w których naprawdę chcę wiedzieć, czy konwersja może zostać dokonana w kontekście mojego wyboru ... –
@MateiDavid 'is_convertible' próbuje symulować definicję * niejawnie wymienialnego *, co uważam za nieco nieintuicyjne. Sama definicja wymaga dostępnego konstruktora kopiowania/przenoszenia. Może w twoim kontekście "is_constructible" ma więcej sensu. – dyp