我可以做这个:
#include <iostream>
int counter;
int main()
{
struct Boo
{
Boo(int num)
{
++counter;
if (rand() % num < 7) Boo(8);
}
};
Boo(8);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这将编译正常,我的计数器结果是21.但是,当我尝试创建Boo传递构造函数参数而不是整数文字的对象时,我得到一个编译错误:
#include <iostream>
int counter;
int main()
{
struct Boo
{
Boo(int num)
{
++counter;
if (rand() % num < 7) Boo(num); // No default constructor
// exists for Boo
}
};
Boo(8);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如何在第二个示例中调用默认构造函数,而不是在第一个示例中调用?这是我在Visual Studio 2017上遇到的错误.
在线C++编译器onlineGDB我得到错误:
error: no matching function for call to ‘main()::Boo::Boo()’ …Run Code Online (Sandbox Code Playgroud) Consider
struct A1 {
constexpr A1& operator=(const A1&) = default;
~A1() {}
};
struct A2 {
constexpr A2& operator=(const A2&) = default;
~A2() = default;
};
struct A3 {
~A3() = default;
constexpr A3& operator=(const A3&) = default;
};
Run Code Online (Sandbox Code Playgroud)
GCC and MSVC accept all three structs. Clang rejects A1 and A2 (but accepts A3), with the following error message:
Run Code Online (Sandbox Code Playgroud)<source>:2:5: error: defaulted definition of copy assignment operator is not constexpr constexpr A1& operator=(const A1&) = default; ^ <source>:6:5: error: …
#include <ranges>
#include <iostream>
#include <string_view>
using namespace std::literals;
int main()
{
auto fn_is_l = [](auto const c) { return c == 'l'; };
{
auto v = "hello"sv | std::views::filter(fn_is_l);
std::cout << *v.begin() << std::endl; // ok
}
{
auto const v = "hello"sv | std::views::filter(fn_is_l);
std::cout << *v.begin() << std::endl; // error
}
}
Run Code Online (Sandbox Code Playgroud)
请参阅:https : //godbolt.org/z/vovvT19a5
<source>:18:30: error: passing 'const std::ranges::filter_view<
std::basic_string_view<char>, main()::
<lambda(auto:15)> >' as 'this' argument discards
qualifiers [-fpermissive]
18 | std::cout << *v.begin() …Run Code Online (Sandbox Code Playgroud) 从版本1.80开始,Cppcheck告诉我
表达式'msg [ipos ++] =校验和(&msg [1],ipos-1)'取决于副作用的评估顺序
在这个代码序列中(简化,data是一个变量)
BYTE msg[MAX_MSG_SIZE]; // msg can be smaller, depending on data encoded
int ipos = 0;
msg[ipos++] = MSG_START;
ipos += encode(&msg[ipos], data);
msg[ipos++] = checksum(&msg[1], ipos-1); // <---- Undefined Behaviour?
msg[ipos++] = MSG_END; // increment ipos to the actual size of msg
Run Code Online (Sandbox Code Playgroud)
并将此视为错误,而不是可移植性问题.
它是C代码(包含在C++主导的项目中),使用C++ 98兼容编译器编译,同时按预期运行数十年.Cppcheck使用C++ 03,C89,自动检测语言运行.
我承认代码应该更好地重写.但在此之前,我试图弄清楚:它真的依赖于评估顺序吗?根据我的理解,正在首先评估正确的操作数(它需要在调用之前),然后msg[ipos]使用ipos最后完成的增量进行赋值(to ).
我错了这个假设,还是只是假阳性?
考虑
using foo = int;
struct A {
typedef A (foo)();
};
Run Code Online (Sandbox Code Playgroud)
GCC 和 ICC 接受该代码段,而 Clang 和 MSVC 拒绝它。Clang 的错误信息是
Run Code Online (Sandbox Code Playgroud)<source>:4:15: error: function cannot return function type 'void ()' typedef A (foo)(); ^ <source>:4:13: error: typedef name must be an identifier typedef A (foo)(); ^ 2 errors generated.
MSVC 说
Run Code Online (Sandbox Code Playgroud)<source>(4,15): error C2091: function returns function typedef A (foo)(); ^
(现场演示)
为什么 Clang 和 MSVC 会产生这个错误?哪些编译器是正确的?
(我专门从标准或任何缺陷报告中寻找报价。)
考虑:
#include <compare>
template<class=void>
constexpr int f() { return 1; }
unsigned int x;
using T = decltype(x <=> f());
Run Code Online (Sandbox Code Playgroud)
GCC 和 MSVC 接受T. Clang 拒绝了它,并显示以下错误消息:
Run Code Online (Sandbox Code Playgroud)<source>:7:26: error: argument to 'operator<=>' cannot be narrowed from type 'int' to 'unsigned int' using T = decltype(x <=> f()); ^ 1 error generated.
(现场演示)
如果模板头 ( template<class=void>) 被移除,或者如果f在 的声明之前显式或隐式实例化T,则 Clang 接受它。例如,Clang 接受:
#include <compare>
template<class=void>
constexpr int f() { return 1; }
unsigned x; …Run Code Online (Sandbox Code Playgroud) 阅读C++ 17,现在可以在if语句中进行多次初始化:
if (int x = func(), y = func2(); x > 0 && y > 0)
{
}
Run Code Online (Sandbox Code Playgroud)
不错的,也结合了C++ 17中的另一个功能,结构化绑定:
if (auto[iter, success] = set.insert("Hello"); success)
{ }
else
{ }
Run Code Online (Sandbox Code Playgroud)
但是,在VisualStudio 2017中无法编译这两个功能.
if (auto[iter, success] = set.insert("Hello"), [iter2, success2] = set.insert("Foo"); success && success2)
{}
else
{}
Run Code Online (Sandbox Code Playgroud)
失踪 ';' 之前','
这是VS2017中的错误还是不可能?
在C++标准中,闭包类型定义如下:
[expr.prim.lambda.closure] lambda表达式的类型(也是闭包对象的类型)是一个唯一的,未命名的非联合类类型,称为闭包类型,其属性如下所述.[...]
该标准似乎并未定义未命名的非联合类类型是否为final.将lambdas实现为最终类的编译器是否符合标准,或者我们是否可以保证可以从lambdas继承?
问题不在于从lambdas继承是否有用:它是有用的.问题是标准是否提供此保证.
std::make_unique()(和类似的功能)有一点问题:
#include <cstdio>
#include <memory>
using namespace std;
struct S
{
S() { printf("ctor\n"); }
~S() { printf("dtor\n"); }
S(S const&) { printf("cctor\n"); }
S(S&&) { printf("mctor\n"); }
};
S foo() { return S(); }
int main()
{
{
printf("--------------- case 1 ---------------\n");
unique_ptr<S> s1 = make_unique<S>( foo() );
}
{
printf("--------------- case 2 ---------------\n");
unique_ptr<S> s2 { new S( foo() ) };
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
--------------- case 1 ---------------
ctor
mctor
dtor
dtor
--------------- case 2 …Run Code Online (Sandbox Code Playgroud) 前几天,我发现这是可能的:
template <class T> struct base {};
struct derived: base<int> {};
int main()
{
// The base class template is accessible here
typename derived::base<double> x;
// from the comments, even this works
typename derived::derived::base<double>::base<int>::base<void> y;
}
Run Code Online (Sandbox Code Playgroud)
我没有回忆过在cppreference或C++教程中读过这个,或者这是在聪明的模板元编程技巧中被利用的(因为我确信它可以).我有几个问题:
c++ inheritance language-lawyer template-meta-programming c++11