std::make_shared
ist eine variadic Funktion Vorlage. Sie geben nur <foo>
als Vorlage-Parameter an, aber Sie benötigen auch eine int
irgendwo dort. Unabhängig davon ist Ihr Ansatz zwangsläufig fehlgeschlagen, da es darauf angewiesen ist, wie die Vorlagenargumente von make_shared
angelegt wurden und es im Allgemeinen umständlich ist, mit Überladungssätzen in C++ zu arbeiten.
Was ich vorschlagen, ist eine Wrapper-Funktion zu erstellen, anstatt:
constexpr auto newfoo(int x)
{
return std::make_shared<foo>(x);
}
Meiner Meinung nach ist es einfacher zu schreiben, lesen und zu verstehen. Wenn Sie wirklich brauchen SFINAE Freundlichkeit und noexcept
, können Sie repeat the body three times:
constexpr auto newfoo(int x)
-> decltype(std::make_shared<foo>(x))
noexcept(noexcept(std::make_shared<foo>(x)))
{ return std::make_shared<foo>(x); }
Ein Makro verwendet werden, kann die obige Erklärung weniger schmerzhaft zu machen.
Wenn Sie wirklich einen Funktionszeiger wollen, scheint dies zu funktionieren:
auto newfoo =
static_cast<std::shared_ptr<foo>(*)(const int&)>(
&std::make_shared<foo, const int&>);
Blick auf make_shared
‚s Erklärung:
template< class T, class... Args >
shared_ptr<T> make_shared(Args&&... args);
Sie benötigen T=foo
und etwas für Args...
liefern . Da Args...
ein Forwarding-Referenzpaket ist, wird es immer entweder auf lvalue-Referenzen oder rvalue-Referenzen schließen. Deshalb ist <foo, const int&>
ein gültiger Satz von Vorlagenparametern und <foo, int>
ist nicht.
constexpr auto newfoo = &std::make_shared<foo, const int&>;
Die Besetzung hier nicht wirklich gebraucht wird:
Wie Zefick in den Kommentaren darauf hingewiesen, all dies kann vereinfacht werden.
+1, aber Sie sollten wahrscheinlich 'const int &' anstelle von 'int &&' in Ihrem "Wenn Sie wirklich wollen" Beispiel verwenden. Wie es ist, const int i = 42; auto f = newfoo (i); 'wird nicht funktionieren. –
@MilesBudnek: guter Punkt, änderte meine Antwort –
'constexpr auto newfoo = std :: make_shared' funktioniert einfach. Warum brauchen wir die Besetzung? –
Zefick