c ++从decltype返回类型中删除noexcept

Mar*_*ork 10 c++ decltype template-meta-programming c++17

#include <functional>
#include <sys/types.h>
#include <sys/socket.h>


std::function<decltype(::bind)> mockbind = ::bind;

int main()
{
}
Run Code Online (Sandbox Code Playgroud)

上面的代码适用于我编译的大多数平台.但是在使用g ++ - 7的ubuntu 14.04上我收到一个错误:

X.cpp:7:65: error: variable ‘std::function<int(int, const sockaddr*, unsigned int) noexcept> mockbind’ has initializer but incomplete type
 std::function<int(int, const sockaddr*, unsigned int) noexcept> mockbind = ::bind;
                                                                 ^~~~~~~~
Run Code Online (Sandbox Code Playgroud)

现在,如果我手动去改变类型 mockbind

std::function<int(int, const sockaddr*, unsigned int) noexcept> mockbind = ::bind;
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,我得到了同样的错误:
现在如果我删除了noexcept

std::function<int(int, const sockaddr*, unsigned int)> mockbind = ::bind;
Run Code Online (Sandbox Code Playgroud)

它按预期编译.

所以问题是我可以应用一些模板代码来删除noexcept返回的类型decltype并使其按预期工作.

Hol*_*Cat 12

一个简单的类专业化技巧应该工作:

template <typename T> struct remove_noexcept
{
    using type = T;
};
template <typename R, typename ...P> struct remove_noexcept<R(P...) noexcept>
{
    using type = R(P...);
};
template <typename T> using remove_noexcept_t = typename remove_noexcept<T>::type;

// ...

std::function<remove_noexcept_t<decltype(::bind)>> mockbind = ::bind;
Run Code Online (Sandbox Code Playgroud)

您可以在某种程度上轻松扩展它以noexcept从[member]函数指针中删除它,这是作为阅读器的练习.

using type = T;如果没有,则可以注释掉是否存在编译时错误,noexcept而不是保持类型不变.