考虑:
class test {
private:
int n;
int impl () const noexcept {
return n;
}
public:
test () = delete;
test (int n) noexcept : n(n) { }
int get () const noexcept(noexcept(impl())) {
return impl();
}
};
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会说不
test.cpp:27:43: error: cannot call member function 'int test::impl() const' with
out object
int get () const noexcept(noexcept(impl())) {
Run Code Online (Sandbox Code Playgroud)
同理:
test.cpp:27:38: error: invalid use of 'this' at top level
int get () const noexcept(noexcept(this->impl())) {
Run Code Online (Sandbox Code Playgroud)
和
test.cpp:31:58: error: invalid use of …Run Code Online (Sandbox Code Playgroud) 对于以下代码
struct X
{
int x;
X() noexcept try : x(0)
{
}
catch(...)
{
}
};
Run Code Online (Sandbox Code Playgroud)
Visual Studio 14 CTP发出警告
警告C4297:'X :: X':函数假定不抛出异常,但确实如此
注意:在函数上指定了__declspec(nothrow),throw(),noexcept(true)或noexcept
这是滥用noexcept吗?或者它是Microsoft编译器中的错误?
我正在修补有效现代C++第91页上的例子,我遇到了一个似乎很奇怪的问题.这段代码
template<typename C>
void doStuff(C& a, C& b) noexcept(noexcept(doStuff(a.front(), b.front()))) {
std::cout << "container version" << std::endl;
}
template<>
void doStuff<int>(int& x, int& y) noexcept {
std::cout << "int version" << std::endl;
}
int main() {
vector<int> v1 = {1, 2, 3};
vector<int> v2 = {4, 5, 6};
int x = 5;
int y = 6;
doStuff(x, y);
doStuff(v1, v2);
}
Run Code Online (Sandbox Code Playgroud)
给我一个错误
错误:请求'a'中的成员'front',这是非类型'int'void doStuff(C&a,C&b)noexcept(noexcept(doStuff(a.front(),b.front()) )){
因此,似乎正在调用doStuff的顶级版本,即使a.front()和b.front()应该返回对int的引用.如果我从代码中删除所有noexcept声明,我得到预期的输出.
这是与gcc 5.4.
我究竟做错了什么?
谢谢
struct foo
{
struct bar {
~bar() {} // no error w/o this line
};
bar *data = nullptr; // no error w/o this line
foo() noexcept = default; // no error w/o this line
};
Run Code Online (Sandbox Code Playgroud)
是的,我知道,还有另一个问题具有完全相同的标题,但是有一个不同的问题(涉及noexcept 运算符而没有嵌套类型).该解决方案建议有(取代的构造foo与
foo() noexcept {}
Run Code Online (Sandbox Code Playgroud)
)改变语义,这里没有必要:这里我们有一个更好的答案(因此问题不是重复).
编译器:Apple LLVM version 9.0.0 (clang-900.0.37),完整的错误信息:
test.cc:44:5: error: default member initializer for 'data' needed within definition of enclosing class 'foo' outside of member functions
foo() noexcept = default;
^
test.cc:41:10: note: …Run Code Online (Sandbox Code Playgroud) 这是value_or()C++ 17标准的定义:
template <class U> constexpr T value_or(U&& v) const&;效果:相当于:
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));备注:如果
is_copy_constructible_v<T> && is_convertible_v<U&&, T>是false,该程序是不正确的.
(右值超载类似)
效果value_or被描述为等同于return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
operator bool是noexcept.operator*是不是 noexcept(即使它没有抛出,可能是因为如果在可选项不包含值时使用UB,它仍然可以失败).但是,我们保证永远不会尝试返回包含的值,除非我们有一个.
所以不能value_or被宣布noexcept给予is_nothrow_copy_constructible<T> && noexcept(static_cast<T>(std::forward<U>(v)))?
[expr.unary.noexcept]的措辞在C++17 中发生了变化。
以前(n4140, 5.3.7 noexcept operator [expr.unary.noexcept]),我的重点是:
- 如果在潜在求值的上下文中表达式将包含,则 noexcept 运算符的结果为 false
(3.1) 对不具有非抛出异常规范 ([except.spec]) 的函数、成员函数、函数指针或成员函数指针的潜在求值调用,除非调用是常量表达式 ([ expr.const]) ...
现在1(7.6.2.6 noexcept 运算符 [expr.unary.noexcept]):
- 除非表达式可能抛出异常 ([except.spec]),否则noexcept 运算符的结果为真。
- 如果函数声明没有 noexcept 说明符,则该声明具有潜在的抛出异常说明,除非...
但是14.5(3)的除非列表未列出constexpr,因此可能会抛出...
1 LF 在评论中添加的指向 C++17 n4659的链接。
constexpr int f(int i) { return i; }
std::cout << boolalpha << noexcept(f(7)) << std::endl;
int a = 7;
std::cout …Run Code Online (Sandbox Code Playgroud) 假设以下 c++17 代码:
#include <type_traits>
namespace dtl
{
struct One
{
explicit One(int);
~One() = default;
One(const One &) = delete;
auto operator=(const One &) -> One & = delete;
auto operator=(One &&) -> One & = delete;
One(One &&); // Throwable, not default;
int m_int;
};
struct Two
{
explicit Two(int);
~Two() = default;
Two(const Two &) = delete;
auto operator=(const Two &) -> Two & = delete;
auto operator=(Two &&) noexcept -> Two & = delete;
Two(Two &&) …Run Code Online (Sandbox Code Playgroud) 通过函数类型与被调用函数定义的函数类型不同的表达式调用函数会导致未定义行为。
void f() noexcept {}; // function type is "noexcept function"
void (*pf)() = f; // variable type is "pointer to function"; initialized by result of [conv.fctptr]([conv.func](f))
int main()
{
(*pf)(); // `*pf`: lvalue expression's function type is "function" (without noexcept!)
}
Run Code Online (Sandbox Code Playgroud)
根据引用的标准,上述调用是否会导致未定义的行为?
c++ function-pointers undefined-behavior language-lawyer noexcept
我很难理解这一点.
double compute(double x, double y) noexcept
{
if (y == 0)
throw std::domain_error("y is zero");
return x / y;
}
Run Code Online (Sandbox Code Playgroud)
这在clang中编译得很好(我没有检查过gcc),但这对我来说似乎是胡说八道.为什么编译器允许noexcept函数包含throw语句?
在关于异常规范的 C++ Primer 上noexcept,据说指向可能抛出隐式(没有异常规范定义,例如:)void(*p)();或显式(void(*p)() noexcept(false);)的函数的指针可以指向任何函数,甚至指向不抛出的函数。
另一方面,一个不能抛出异常的函数指针(noexcept例如void(*p) noexcept;)只能指向一个不会抛出异常的函数。
我发现这非常合乎逻辑,因为第一个指针可以从抛出函数指针指向非抛出函数,而第二个指针也很合乎逻辑。
我尝试过这个来了解更多:
void func1(){ // may throw
std::cout << "func1()\n";
}
void func2() noexcept(false){ // may throw
std::cout << "func2()\n";
}
void func3() noexcept(true){ // won't throw
std::cout << "func3()\n";
}
void func4() noexcept{ // won't throw
std::cout << "func4()\n";
}
int main(int argc, char* argv[]){
void(*pFn1)();
pFn1 = func1; // OK
pFn1 = func2; // OK
pFn1 = func3; // OK
pFn1 …Run Code Online (Sandbox Code Playgroud) c++ ×10
noexcept ×10
c++17 ×3
c++11 ×2
c++14 ×1
compilation ×1
constexpr ×1
exception ×1
gcc ×1
stdoptional ×1
tags ×1
templates ×1
visual-c++ ×1