Ich habe eine Vorlage, die so aussieht
template <typename T> class Foo
{
public:
Foo(const T& t) : _t(t) {}
private:
const T _t;
};
Gibt es eine clevere Methode zur Metaprogrammierung von Vorlagen, um die Verwendung einer const-Referenz in Fällen zu vermeiden, in denen der Argumenttyp trivial ist wie ein Bool oder ein Zeichen? mögen:
Foo(stl::smarter_argument<T>::type t) : _t(t) {}
Foo
.Antworten:
Ich denke, das richtige Merkmal ist
is_scalar
. Dies würde wie folgt funktionieren:Bearbeiten:
Das Obige ist immer noch ein bisschen altmodisch, danke @HolyBlackCat, dass du mich an diese knappere Version erinnert hast:
quelle
is_fundamental
funktionieren?= void
bedeutet, dass es einen Standardtyp hat, der ungültigsmarter_argument<T>
istsmarter_argument<T, void>
. Ich habe einen Namen für dieses Argument weggelassen, da wir ihn nicht brauchen, daherclass = void
ohne Namen. Es ist wichtig, dass derstd::enable_if_t
Fall, dass er aktiviert ist, ebenfalls ungültig ist, damit er dem Standardtyp entspricht.template <typename T> using smarter_argument = std::conditional_t<std::is_scalar_v<T>, T, const T &>;
.Ich würde vorschlagen,
sizeof(size_t)
(odersizeof(ptrdiff_t)
) zu verwenden, die eine "typische" Größe für Ihre Maschine zurückgibt, in der Hoffnung, dass jede Variable dieser Größe in ein Register passt. In diesem Fall können Sie es sicher als Wert übergeben. Darüber hinaus ist es, wie von @ n314159 vorgeschlagen (siehe Kommentare am Ende dieses Beitrags), sicherzustellen, dass die Variable auch vorhanden isttrivialy_copyable
.Hier ist eine C ++ 17-Demo:
quelle
struct Foo { void bar(){ }; int i; }; std::cout << sizeof(&Foo::i) << std::endl; //prints 8 std::cout << sizeof(&Foo::bar) << std::endl; //prints 16
<=
stattdessen verwenden==
, auf den meisten Computern wird Ihr aktueller Codechar
beispielsweise als Referenz verwendet, wenn ich das richtig sehe.T
sie trivial kopierbar sind. Zum Beispiel ist ein gemeinsam genutzter Zeiger nur doppelt so groß wiesize_t
auf meiner Plattform und kann mit nur einem Zeiger implementiert werden, sodass er dieselbe Größe hat. Aber Sie möchten auf jeden Fall den shared_ptr nach const ref und nicht nach value nehmen.Ich würde das Schlüsselwort C ++ 20 verwenden
requires
. Genau so:Sie können den Code online ausführen , um die folgende Ausgabe anzuzeigen:
quelle