c++ - 重载模板函数的 constexpr 别名

标签 c++ templates constexpr

尝试为该类的特定构造函数在特定类类型上使用别名 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=fooArgs... 的东西.自 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/

相关文章:

java - JNI 返回 Signal 7 函数试图从 C++ 调用 Java

c++ - 获取 c 数组上 begin 的返回类型

c++ - constexpr 变量的初始化

c++ - 方法体中的静态变量是否由所有实例共享

java - 消息传递如何帮助实现 OOP 中的修饰符?

C++通过类模板函数中的指针访问类方法

c++ - 如何创建特定的 std::vector 迭代器?

c++ - 使用 gcc 捕获 lambda 错误,使用 clang 进行编译

c++ - 在运行时使用模板化的 constexpr

c++ - 如何将 char *argv[] 从 Main 函数指向表