Tôi sẽ đề nghị sử dụng sizeof(size_t)
(hoặc sizeof(ptrdiff_t)
) trả về kích thước "điển hình" liên quan đến máy của bạn với hy vọng rằng bất kỳ biến nào có kích thước này phù hợp với một thanh ghi. Trong trường hợp đó bạn có thể vượt qua nó một cách an toàn. Hơn nữa, như được đề xuất bởi @ n314159 (xem bình luận ở cuối bài này), rất hữu ích để đảm bảo rằng biến cũng là trivialy_copyable
.
Đây là bản demo 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
}