尝试为该类的特定构造函数在特定类类型上使用别名 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>);
我做错了什么?
最佳答案
std::make_shared
是一个可变函数模板。您只指定 <foo>
作为模板参数,但您还需要 int
在那里的某个地方。无论如何,您的方法注定会失败,因为它依赖于 make_shared
的方式。的模板参数被布置好,因为在 C++ 中使用重载集通常很麻烦。
我的建议是改为创建一个包装函数:
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&>;
这里真的不需要类型转换。
关于c++ - 重载模板函数的 constexpr 别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46222206/