Sto cercando di capire std::is_convertible
in C++ 11. Secondo cppreference.com, std::is_convertible<T,U>::value
dovrebbe valutare su 1 iff "Se un valore immaginario di tipo T
può essere utilizzato nell'istruzione di ritorno di una funzione che restituisce U
". La formulazione non dice nulla su dove quella funzione potrebbe essere dichiarata, però. Cosa ci si dovrebbe aspettare quando il costruttore di copie di U
è privato? Cosa ci si dovrebbe aspettare quando T
è un riferimento lvalue?C++ 11 std: comportamento is_convertible con il costruttore di copie private
esempio considerare questo codice:
#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
}
sto usando gcc-4.8.2
o clang-3.4
(nessuna differenza di uscita), e ho compilato con:
{g++|clang++} -std=c++11 -Wall -Wextra eg.cpp -o eg
Qui, std::is_convertible< Ref_A, A >
rapporti 0
. Tuttavia, è possibile vedere che Fact_A::f
restituisce un oggetto di tipo A
e un rvalue di tipo Ref_A
viene utilizzato nella dichiarazione di reso. Il problema è che il costruttore di copie di A
è private
, in modo che la funzione non possa essere posizionata altrove. Il comportamento attuale è corretto rispetto allo standard?
Seconda domanda. Se rimuovo private
, l'output diventa 1 1 1
. Cosa significa l'ultimo 1
? Che cos'è un "rvalue di tipo A&
"? È un riferimento di valore? Perché potresti notare che ho eliminato esplicitamente il costruttore di spostamenti di A
. Di conseguenza, non posso dichiarare Fact_A::g
. Ma ancora, std::is_convertible< A&, A >
riporta 1
.
Grazie per il riferimento. Oltre a ciò che hai detto, c'è più testo direttamente sotto la bozza che hai citato, che menziona specificamente i problemi di contesto. Lo accetterò. Immagino che rimanga una domanda persistente sul fatto che lo standard stia facendo la cosa giusta. Quello che non mi piace è che 'is_convertible' sembra inutilmente legato all'accessibilità del costruttore di' To', che non ha nulla a che fare con 'From', o la relazione tra' From' e 'To'. Posso immaginare situazioni in cui voglio davvero sapere se la conversione può essere fatta in un contesto di mia scelta ... –
@MateiDavid 'is_convertible' prova a simulare la definizione di * implicitamente convertibile *, che trovo un po 'non intuitivo. Questa definizione richiede di per sé un costruttore di copia/spostamento accessibile. Forse nel tuo contesto, 'is_constructible' ha più senso. – dyp