2017-10-13 2 views
1

Il est mentionné here et there qu'il est parfois préférable de passer par valeur au lieu de passer par référence. À la lumière de cela, est-il possible de sélectionner certains types à transmettre en fonction des modèles variés d'acheminement parfaits?Gabarit variadé d'acheminement parfait avec valeur de passage pour les types sélectionnés

template<typename... Args> 
void foo(Args&&...); // passes everything by reference 

template<typename... Args> 
void foo(Args...); // passes everything by value 

template<typename... Args> 
void foo(std::conditional_t<is_selected_v<Args>, Args, Args&&>...); // won't deduce types 

template<typename... Args> 
void foo(...); // this is wrong :) 

Remarque ne pas être en mesure de déduire les types signifie qu'il ne fonctionnera pas pour les constructeurs

+0

uhm, je dirais que les fonctions de transfert parfaites sont presque toujours utilisées lorsque inline est possible/probable, ce qui rend le besoin de passer par valeur fa r moins évident ... –

+0

Souhaitez-vous passer tous les arguments par valeur si certaines conditions sont remplies, ou voulez-vous en transmettre une par valeur et une autre par référence? Ce dernier ne semble pas possible ... – Knoep

+0

@Knoep Ce dernier. Je ne peux pas penser à tout ce qui peut faire cela, d'où la question –

Répondre

2

Je pense que le mieux que nous puissions faire est

template<typename T> 
using pass_policy_t = std::conditional_t< 
    std::is_scalar<std::decay_t<T>>::value, 
    std::decay_t<T>, 
    T&&>; 

template<typename... Args> 
void foo_impl(pass_policy_t<Args>...); 

template<typename... Args> 
inline void foo(Args&&... args) 
{ 
    foo_impl<Args...>(std::forward<Args>(args)...); 
} 

où pass_policy_t calcule le type de passe réel (en l'exemple ci-dessus, les types scalaires se désintègrent). Bien sûr, il n'y a pas de garantie foo sera opimisé, de toute façon je serais heureux de voir une situation raisonnable où il ne le fait pas ... :) voici live snippet pour essayer ...

par souci d'exhaustivité, il y avait une proposition standard sur le problème (n3445) mais il semble allé nulle part ... de toute façon, 1) il soutient le suspect que ce n'est pas possible actuellement sans plus de support de langue et 2) il montre que même ayant une politique de valeur de passage contrôle complet du programmeur, il ne serait pas optimal de toute façon sans quelque chose comme is_fast_pass trait intrinsèque ...

+0

C'est une bonne idée! Avez-vous fait quelques tests que cela fonctionne réellement dans la plupart des circonstances? – Knoep

+0

@Knoep J'ai ajouté une politique de réussite concrète pour les tests; tests de base font en ligne autant que je peux dire ... –

+0

Yup, essayé avec 'is_empty' et les constructeurs de copie personnalisée. Les choses sont copiées quand elles devraient l'être. – Knoep