Когда у меня есть следующий псевдокласс:
template <class T> class tmplClass
{
void doSomething(T input);
};
Есть ли способ изменить void doSomething(T input)
в void doSomething(const T& input)
когда sizeof (T) больше, то архитектура системы.
Значит, когда у вас есть tmplClass<char> c;
например, использовать void doSomething(T input)
и когда у вас есть tmplClass<[another big class with lots of variables]>
использование void doSomething(const T& input)
Конечно:
template<typename T, bool=true>
struct eff_arg {
typedef T type;
};
template<typename T>
struct eff_arg<T, (sizeof(T)>sizeof(int))> {
typedef T const& type;
};
// C++11 addition
template<typename T>
using EffArg = typename eff_arg<T>::type;
использовать:
template <class T> class tmplClass
{
// C++11
void doSomething(EffArg<T> input);
// C++03
void doSomething(typename eff_arg<T>::type input);
};
и заменить sizeof(int)
с любым типом, который вы хотите использовать в качестве «точки, где вы хотите передать в качестве ссылки, а не по значению».
Обратите внимание, что размер параметра — посредственный способ принять это решение: очень маленький класс (даже меньше, чем указатель!) Может иметь глубокую семантику копирования, где большая структура дублируется при дублировании. И часто отрезок не должен быть размером int
или указатель, но больше, чем это, потому что косвенное обращение имеет цену.
Идея может заключаться в том, чтобы копировать только объекты, которые не управляют ресурсами и являются достаточно маленькими. std::is_trivially_copyable<T>::value && (sizeof(T) <= 2*sizeof(void*))
может быть вид проверки, которую вы должны сделать перед прохождением T
а не T const&
когда вам не нужно копировать данные.
Это приводит к следующему:
template<typename T, bool=true>
struct eff_arg {
typedef T const& type;
};
template<typename T>
struct eff_arg<T,
std::is_trivially_copyable<T>::value
&& (sizeof(T)<=2*sizeof(void*))
> {
typedef T type;
};
template<typename T>
using EffArg = typename eff_arg<T>::type;
Да легко
#include <type_traits>
template <typename T> struct Foo
{
void do_something(typename std::conditional<(sizeof(T) > sizeof(void *)),
T const &, T>::type x)
{
// ... use "x"}
// ...
};
Возможно, вы захотите присвоить результирующий тип псевдониму некоторого типа для легкого повторного использования.
Как подсказывает @Yakk, было бы неплохо добавить std::is_trivially_copyable<T>::value
к условию, чтобы избежать случайного копирования чего-то дорогого, чтобы скопировать или что может бросить.