超载模板功能的constexpr别名

Constexpr alias of overloaded template function

本文关键字:constexpr 别名 功能 超载      更新时间:2023-10-16

试图在该类的特定构造函数的特定类类型上求和。我最好的尝试:

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 variadic函数模板。您仅将<foo>指定为模板参数,但是您也需要在其中某个地方进行int。无论如何,您的方法一定会失败,因为它依赖于make_shared的模板参数的布局,并且因为在C 中使用过载集通常很麻烦。

我建议的是创建包装器功能:

constexpr auto newfoo(int x)
{
    return std::make_shared<foo>(x);
}

我认为,编写,阅读和理解更容易。如果您确实需要Sfinae-Fricrignliness和noexcept,则可以重复三遍身体:

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提供CC_7。由于Args...是一个转发参考包,因此它始终将推导为 lvalue参考 rvalue参考。这就是为什么<foo, const int&>是有效的模板参数集,而<foo, int>不是。

正如Zefick在评论中指出的那样,所有这些都可以简化为:

constexpr auto newfoo = &std::make_shared<foo, const int&>;

在这里真的不需要演员。