6

ho le seguenti due funzioni sovraccarichi di modello:const unificante T & e T && sovraccarica

template<typename T> 
optional<T> some(const T& x) 
{ 
    return optional<T>(x); 
} 

template<typename T> 
typename std::enable_if<std::is_rvalue_reference<T&&>::value, optional<T> >::type 
some(T&& x) 
{ 
    return optional<T>(std::move(x)); 
} 

Il mio primo tentativo di unificare i sovraccarichi tramite inoltro perfetta riuscita:

template<typename T> 
optional<T> some(T&& x) 
{ 
    return optional<T>(std::forward<T>(x)); 
} 

error: forming pointer to reference type 'const std::basic_string<char>&' 

come ha fatto il mio secondo tentativo:

C'è un modo pulito per unificare i sovraccarichi, o devo solo vivere con averli?

+1

È necessario fornire una definizione di cosa sia 'opzionale <>'. –

+0

È fondamentalmente un clone giocattolo di 'boost :: optional'. – fredoverflow

+1

... Eppure la domanda è valida, puoi fornire la definizione? Ho la sensazione che il problema sia con l'interfaccia di 'opzionale' (cioè l'inoltro perfetto è la soluzione per' some', potrebbe essere necessario modificarlo per adattarlo 'opzionale') –

risposta

1

In generale, il modo migliore per farlo è quello di prendere l'oggetto per valore e lasciare che il chiamante decidere se copiare o spostare esso:

template<typename T> 
optional<T> some(T x) 
{ 
    return optional<T>(std::move(x)); 
} 

Se il chiamante chiama con un temporaneo o usa std::move sul loro valore, quindi viene spostato. Altrimenti è copiato.

Sì, questo significa che eseguirai una mossa aggiuntiva (che, se il movimento è lo stesso della copia, significa fare due copie). Se questo è un problema di prestazioni significativo per te, dovrai utilizzare l'implementazione dei due overload.

4

Non ho dimestichezza con il vostro optional, ma forse si dovranno aggiungere:

typename remove_const<...>::type 

intorno agli remove_reference in due punti. (poiché il tuo primo sovraccarico della tua soluzione a 2 sovraccarichi - che presumo sta superando tutti i tuoi test) fa effettivamente un remove_const quando dichiari optional<T>).

+0

Non dovrebbe essere' remove_cv' solo per essere al sicuro? – pmr

+1

Se è ciò che si desidera. L'attuale soluzione a 2 sovraccarichi rifiuta semplicemente gli lvalues ​​qualificati per uso volatile. È difficile per me dire cosa si desidera senza un esempio di codice completo. –