尝试在特定类类型上为该类的特定构造函数设置make_shared别名。我最好的尝试:
class foo { public: foo(int x) : y(x) {} int y; };
constexpr auto newfoo = static_cast<std::shared_ptr<foo>(*)(int)>(std::make_shared<foo>);
收率:
error: invalid static_cast from type ‘<unresolved overloaded function type>’ to type ‘std::shared_ptr<foo> (*)(int)’
constexpr auto newfoo = static_cast<std::shared_ptr<foo>(*)(int)>(std::make_shared<foo>);
我做错了什么?
答案 0 :(得分:4)
std::make_shared
是可变参数函数模板。您只是将<foo>
指定为模板参数,但在那里您还需要int
。无论如何,您的方法必然会失败,因为它依赖于make_shared
模板参数的布局方式,并且因为在C ++中使用重载集通常很麻烦。 / p>
我建议改为创建一个包装函数:
constexpr auto newfoo(int x)
{
return std::make_shared<foo>(x);
}
在我看来,写作,阅读和理解更容易。如果确实需要SFINAE友好性和noexcept
,您可以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); }
可以使用宏来减轻上述声明的痛苦。
如果你真的想要一个函数指针,这似乎有效:
auto newfoo =
static_cast<std::shared_ptr<foo>(*)(const int&)>(
&std::make_shared<foo, const int&>);
查看make_shared
的声明:
template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );
您需要为T=foo
提供Args...
和其他内容。由于Args...
是转发参考包,因此它总是推导为左值引用或右值引用。这就是为什么<foo, const int&>
是一组有效的模板参数而<foo, int>
不是。
正如Zefick在评论中指出的那样,所有这些都可以简化为:
constexpr auto newfoo = &std::make_shared<foo, const int&>;
这里不需要演员。