2017-08-30 73 views
7
#include <functional> 
#include <sys/types.h> 
#include <sys/socket.h> 


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

int main() 
{ 
} 

上面的代码可以在我编译的大多数平台上工作。但在自定义g的Ubuntu 14.04 ++ - 7我得到一个错误:C++从decltype中删除noexcept返回的类型

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; 
                   ^~~~~~~~ 

现在,如果我手动去改的mockbind

std::function<int(int, const sockaddr*, unsigned int) noexcept> mockbind = ::bind; 

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

std::function<int(int, const sockaddr*, unsigned int)> mockbind = ::bind; 

它按预期进行编译。

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

+0

不是'auto mockbind = :: bind'做你想要的吗? – whoan

+0

@whoan:不,因为它不会创建一个'std :: function <>'类型的对象。如果没有它,很难将funcotors绑定到“mockbind”。 –

回答

10

一个简单的类专业化伎俩应工作:

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; 

你可以稍微轻松地扩展它来删除[成员]函数指针noexcept,剩下的作为锻炼; Tibial给读者。

如果您希望在没有noexcept的情况下发生编译时错误,而不是保持类型不变,那么您可以注释掉using type = T;

+1

我认为这也可以为成员函数添加专业化 – SirGuy

+0

@SirGuy是的,它应该。为了简单起见,我决定不打扰他人。 – HolyBlackCat

+0

看起来。好。当我到家时,我会在今晚测试它 –