Eu sugeriria usar sizeof(size_t)
(ou sizeof(ptrdiff_t)
) que retorne um tamanho "típico" relacionado à sua máquina com a esperança de que qualquer variável desse tamanho se encaixe em um registro. Nesse caso, você pode passá-lo com segurança por valor. Além disso, como sugerido por @ n314159 (consulte os comentários no final deste post), é útil garantir que a variável também seja trivialy_copyable
.
Aqui está uma demonstração do C ++ 17:
#include <array>
#include <ccomplex>
#include <iostream>
#include <type_traits>
template <typename T>
struct maybe_ref
{
using type = std::conditional_t<sizeof(T) <= sizeof(size_t) and
std::is_trivially_copyable_v<T>, T, const T&>;
};
template <typename T>
using maybe_ref_t = typename maybe_ref<T>::type;
template <typename T>
class Foo
{
public:
Foo(maybe_ref_t<T> t) : _t(t)
{
std::cout << "is reference ? " << std::boolalpha
<< std::is_reference_v<decltype(t)> << std::endl;
}
private:
const T _t;
};
int main()
{
// with my machine
Foo<std::array<double, 1>> a{std::array<double, 1>{}}; // <- by value
Foo<std::array<double, 2>> b{std::array<double, 2>{}}; // <- by ref
Foo<double> c{double{}}; // <- by value
Foo<std::complex<double>> d{std::complex<double>{}}; // <- by ref
}