我听说noexcept
将成为C ++ 17中函数类型的一部分。这会有什么不同?这是否意味着我们必须在模板中区分noexcept
和非noexcept
函数和成员函数(这将使我们必须编写的样板代码量增加一倍)?
例如,对于与函数指针匹配的当前模板:
template<typename R, typename... Args>
struct Foo<R (*)(Args...)> {};
我们需要额外的:
template<typename R, typename... Args>
struct Foo<R (*)(Args...) noexcept> {};
这只适用于旧的功能。对于成员函数,我们已经有const
,volatile
和ref-qualifiers,产生了大量的组合。添加noexcept
会增加两倍。
答案 0 :(得分:2)
如果他们盲目地改变了事物以使noexcept
资格成为函数指针类型的一部分,那么他们将破坏大量的代码,通用而不是。因此,有一个后门。
In accord with P0021R1,任何指向noexcept
限定函数的指针都可以隐式转换为指向非noexcept
限定函数的指针。指向具有此类资格的成员函数的指针也是如此。
事实上,建立这个漏洞似乎是提案中大约2/3的语言。
答案 1 :(得分:1)
除了@NicolBolas回答之外,我想指出两个专业化:
// 1
template<typename R, typename... Args>
struct Foo<R (*)(Args...)> {};
和
// 2
template<typename R, typename... Args>
struct Foo<R (*)(Args...) noexcept> {};
然后Foo<decltype(fun)>
将匹配第一个
int fun1(int) {}
和
的第二个int fun2(int) noexcept {}
还给出了两个重载(不用说我们可以在异常规范上重载,因为会改变参数的类型):
int foo(int (*a)(int)); // 1
int foo(int (*a)(int) noexcept); // 2
编译器将为fun1
选择第一个重载,为fun2