Я б запропонував використовувати sizeof(size_t)
(або sizeof(ptrdiff_t)
), який повертає "типовий" розмір, пов'язаний з вашою машиною, з надією, що будь-яка змінна такого розміру вписується в реєстр. У цьому випадку ви можете сміливо передавати його за значенням. Більше того, як запропонував @ n314159 (див. Коментарі в кінці цього допису), корисно переконатися, що змінна також є trivialy_copyable
.
Ось демонстрація 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
}