Eu tenho um modelo que se parece com isso
template <typename T> class Foo
{
public:
Foo(const T& t) : _t(t) {}
private:
const T _t;
};
Existe uma maneira inteligente de metaprogramação de modelos para evitar o uso de uma referência const nos casos em que o tipo de argumento é trivial como um bool ou char? gostar:
Foo(stl::smarter_argument<T>::type t) : _t(t) {}
Foo
.Respostas:
Eu acho que o traço de tipo certo é
is_scalar
. Isso funcionaria da seguinte maneira:Editar:
A descrição acima ainda é um pouco antiga, obrigado @HolyBlackCat por me lembrar desta versão mais concisa:
fonte
is_fundamental
funcionar também?= void
significa que ele tem um tipo padrão que é nulo; portanto, usarsmarter_argument<T>
é realmentesmarter_argument<T, void>
. Deixei um nome para esse argumento, pois não precisamos dele, portanto,class = void
sem nome. É importante que ostd::enable_if_t
caso de estar ativado também seja nulo para que ele corresponda ao tipo padrão.template <typename T> using smarter_argument = std::conditional_t<std::is_scalar_v<T>, T, const T &>;
.Eu sugeriria usar
sizeof(size_t)
(ousizeof(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 sejatrivialy_copyable
.Aqui está uma demonstração do C ++ 17:
fonte
struct Foo { void bar(){ }; int i; }; std::cout << sizeof(&Foo::i) << std::endl; //prints 8 std::cout << sizeof(&Foo::bar) << std::endl; //prints 16
<=
vez de==
, na maioria das máquinas, o código atual usa,char
por exemplo, uma referência, se eu achar certo.T
é trivialmente copiável. Por exemplo, um ponteiro compartilhado tem apenas o dobro do tamanho dasize_t
minha plataforma e pode ser implementado com apenas um ponteiro, reduzindo-o ao mesmo tamanho. Mas você definitivamente quer pegar o shared_ptr por const ref e não por valor.Eu usaria a palavra-chave C ++ 20
requires
. Bem desse jeito:Você pode executar o código online para ver a seguinte saída:
fonte