У меня есть шаблон, который выглядит так
template <typename T> class Foo
{
public:
Foo(const T& t) : _t(t) {}
private:
const T _t;
};
Есть ли хитрый способ метапрограммирования шаблонов, чтобы избежать использования константной ссылки в тех случаях, когда тип аргумента тривиален, как bool или char? подобно:
Foo(stl::smarter_argument<T>::type t) : _t(t) {}
Foo
.Ответы:
Я думаю, что правильная черта типа
is_scalar
. Это будет работать следующим образом:Редактировать:
Выше все еще немного старомодно, спасибо @HolyBlackCat за напоминание мне об этой более краткой версии:
источник
is_fundamental
работать также?= void
означает, что он имеет тип по умолчанию void, поэтому использованиеsmarter_argument<T>
фактическиsmarter_argument<T, void>
. Я оставил имя для этого аргумента, так как оно нам не нужно, следовательно,class = void
без имени. Важно, чтобыstd::enable_if_t
в случае, если он включен, он также был недействительным, чтобы соответствовать типу по умолчанию.template <typename T> using smarter_argument = std::conditional_t<std::is_scalar_v<T>, T, const T &>;
.Я бы предложил использовать
sizeof(size_t)
(илиsizeof(ptrdiff_t)
), который возвращает «типичный» размер, связанный с вашей машиной, в надежде, что любая переменная этого размера вписывается в регистр. В этом случае вы можете безопасно передать его по значению. Более того, как предлагает @ n314159 (см. Комментарии в конце этого поста), полезно убедиться, что переменная тожеtrivialy_copyable
.Вот демонстрация C ++ 17:
источник
struct Foo { void bar(){ }; int i; }; std::cout << sizeof(&Foo::i) << std::endl; //prints 8 std::cout << sizeof(&Foo::bar) << std::endl; //prints 16
<=
вместо==
, на большинстве машин ваш текущий код принимает,char
например, по ссылке, если я правильно понимаю.T
быть легко копируемым. Например, общий указатель вsize_t
моей платформе только вдвое больше размера, и его можно реализовать с помощью всего одного указателя, уменьшив его до того же размера. Но вы определенно хотите взять shared_ptr по const ref, а не по значению.Я бы использовал ключевое слово C ++ 20
requires
. Просто так:Вы можете запустить код онлайн, чтобы увидеть следующий вывод:
источник