小编cpp*_*ner的帖子

如果没有默认构造函数,为什么不编译?

我可以做这个:

#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)

c++ constructor scope default-constructor most-vexing-parse

70
推荐指数
2
解决办法
5193
查看次数

Declaring defaulted assignment operator as constexpr: which compiler is right?

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:

<source>:2:5: error: defaulted definition of copy assignment operator is not constexpr
    constexpr A1& operator=(const A1&) = default;
    ^
<source>:6:5: error: …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer constexpr c++17

31
推荐指数
2
解决办法
1040
查看次数

为什么 std::ranges::filter_view 对象必须是非常量才能查询其元素?

#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)

c++ standards constants c++20 std-ranges

30
推荐指数
2
解决办法
694
查看次数

确定"未知的评估顺序"

从版本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 ).

我错了这个假设,还是只是假阳性?

c c++ static-analysis operator-precedence cppcheck

21
推荐指数
2
解决办法
1411
查看次数

为什么 Clang 和 MSVC 不像带有一组冗余括号的成员 typedef 声明?

考虑

using foo = int;

struct A {
    typedef A (foo)();
};
Run Code Online (Sandbox Code Playgroud)

GCC 和 ICC 接受该代码段,而 Clang 和 MSVC 拒绝它。Clang 的错误信息是

<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.
Run Code Online (Sandbox Code Playgroud)

MSVC 说

<source>(4,15): error C2091: function returns function
    typedef A (foo)();
              ^
Run Code Online (Sandbox Code Playgroud)

现场演示

为什么 Clang 和 MSVC 会产生这个错误?哪些编译器是正确的?

(我专门从标准或任何缺陷报告中寻找报价。)

c++ typedef language-lawyer

20
推荐指数
1
解决办法
383
查看次数

三路比较和constexpr函数模板:哪个编译器是对的?

考虑:

#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 拒绝了它,并显示以下错误消息:

<source>:7:26: error: argument to 'operator<=>' cannot be narrowed from type 'int' to 'unsigned int'
using T = decltype(x <=> f());
                        ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

现场演示

如果模板头 ( 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++ language-lawyer spaceship-operator constexpr c++20

19
推荐指数
1
解决办法
616
查看次数

if语句中没有编译的结构化绑定初始化程序

阅读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++ c++17 structured-bindings

16
推荐指数
1
解决办法
700
查看次数

lambda的遗传是否由标准保证?

在C++标准中,闭包类型定义如下:

[expr.prim.lambda.closure] lambda表达式的类型(也是闭包对象的类型)是一个唯一的,未命名的非联合类类型,称为闭包类型,其属性如下所述.[...]

该标准似乎并未定义未命名的非联合类类型是否为final.将lambdas实现为最终类的编译器是否符合标准,或者我们是否可以保证可以从lambdas继承?

问题不在于从lambdas继承是否有用:它是有用的.问题是标准是否提供此保证.

c++ lambda standards final language-lawyer

16
推荐指数
1
解决办法
813
查看次数

对于使用聚合初始化的结构,避免在make_unique/make_shared/emplace/etc中进行额外移动

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)

c++ c++11 c++14 c++17

14
推荐指数
1
解决办法
498
查看次数

从特定专业化继承时可访问的模板基类?

前几天,我发现这是可能的:

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++标准和cppreference中记录在哪里?
  • 是否有任何模板元编程技巧利用这个?

c++ inheritance language-lawyer template-meta-programming c++11

14
推荐指数
1
解决办法
272
查看次数