std::make_shared
jest szablonem funkcji wariancji . Jako parametr szablonu podajesz tylko <foo>
, ale potrzebujesz też gdzieś tam int
. Bez względu na to, twoje podejście musi zakończyć się niepowodzeniem, ponieważ zależy od tego, jak argumenty szablonu zostały przedstawione i dlatego, że praca z zestawami przeciążeniowymi w C++ jest na ogół uciążliwa.
Co proponuję jest utworzyć funkcję otoki Zamiast:
constexpr auto newfoo(int x)
{
return std::make_shared<foo>(x);
}
Moim zdaniem łatwiej jest pisać, czytać i rozumieć. Jeśli naprawdę trzeba SFINAE obsługi oraz noexcept
, można 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); }
Makro może zostać wykorzystane do powyższego zgłoszenia mniej bolesne.
Jeśli naprawdę chcesz wskaźnik funkcji, to wydaje się działać:
auto newfoo =
static_cast<std::shared_ptr<foo>(*)(const int&)>(
&std::make_shared<foo, const int&>);
Spójrz na make_shared
„deklarację:
template< class T, class... Args >
shared_ptr<T> make_shared(Args&&... args);
Trzeba podać T=foo
i coś dla Args...
. Ponieważ Args...
jest paczką referencyjną do przekazywania, zawsze będzie ona wydedukować wartości wartości odniesienia lub wartości rvalue. Dlatego właśnie <foo, const int&>
jest prawidłowym zbiorem parametrów szablonu, a <foo, int>
nie jest.
Jak Zefick zauważył w komentarzach, wszystko to można uprościć do:
constexpr auto newfoo = &std::make_shared<foo, const int&>;
Obsada nie jest naprawdę potrzebne tutaj.
+1, ale prawdopodobnie powinieneś użyć 'const int &' zamiast 'int &&' w swoim przykładzie "jeśli naprawdę chcesz". Jak to jest, 'const int i = 42; auto f = newfoo (i); 'nie zadziała. –
@MilesBudnek: dobry punkt, zmieniono moją odpowiedź –
'constexpr auto newfoo = std :: make_shared' po prostu działa. Dlaczego potrzebujemy obsady? –
Zefick