小编Yks*_*nen的帖子

拥有多个 const 限定符是否合法?

由于对 的放置进行了一些讨论const,我开始怀疑是否可以const对同一类型有多个限定符:

#include <iostream>

int main()
{
    const const int a = 5;
    std::cout << a;
}
Run Code Online (Sandbox Code Playgroud)

别担心,我不会写这样的代码

结果,clang 和 MSVC 接受了带有警告的代码,但 GCC 拒绝了它:https : //godbolt.org/z/TdYnvc

哪个编译器是对的?

c++ language-lawyer

19
推荐指数
3
解决办法
324
查看次数

用纯说明符覆盖虚函数是否有效?

注意:我不问这样做是否合理,或者这是否是好的设计。我只是问这是否是明确定义的行为,以及结果是否符合预期。

我遇到了以下类层次结构:

struct A
{
    virtual void foo() = 0;
};

struct B: public A
{
    void foo() override 
    {
        std::cout << "B::foo()\n";
    }
};

struct C: public B
{
    virtual void foo() = 0;
};

struct D: public C
{
    void foo() override
    {
        std::cout << "D::foo()\n";
    }
};

int main()
{
    A* d = new D;
    d->foo(); //outputs "D::foo()"
    // A* c = new C; // doesn't compile as expected
}
Run Code Online (Sandbox Code Playgroud)

这段代码定义得好吗?我们是否允许使用纯说明符覆盖定义?

c++ overriding pure-virtual language-lawyer

18
推荐指数
1
解决办法
547
查看次数

你可以#define _min吗?

跟进Do preprocessor Defines replacement in `operator""_name`的评论中的讨论

根据cppreference,保留标识符包括

在全局命名空间中,以下划线开头的标识符。

据我所知,宏不是命名空间的一部分,因此据此#define _min不应使我的程序格式错误,无需诊断。但这样做真的可以吗?我是否可以保证兼容的编译器永远不会以可能被该宏破坏的方式使用该标识符?

c++ language-lawyer

11
推荐指数
1
解决办法
322
查看次数

找不到 Boost(缺少:unit_test_framework)(找到版本“1.71.0”)

我需要使用 boost unit_test_framework 并且我使用 Cmake 命令来找到它:

cmake_minimum_required(VERSION 3.15)
project(My_String)

set(CMAKE_CXX_STANDARD 17)
set(Boost_USE_STATIC_LIBS OFF)
set(SOURCE_FILES MyStringTest.cpp)
set(BOOST_ROOT "C:\\Program Files\\boost\\boost_1_71_0")

find_package(Boost REQUIRED COMPONENTS unit_test_framework)

include_directories(${Boost_INCLUDE_DIR})
include_directories(../src)

add_executable (Boost_Tests_run ${SOURCE_FILES})

target_link_libraries (Boost_Tests_run Boost::unit_test_framework)
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

Could NOT find Boost (missing: unit_test_framework) (found version
  "1.71.0")
Run Code Online (Sandbox Code Playgroud)

我能做什么来修复它?

c++ boost cmake

7
推荐指数
1
解决办法
7808
查看次数

为什么当我使用std:vector和operator []在超出范围的情况下不会得到异常?

为什么当我使用下面的代码时不会超出范围?

std::vector<int> v;
v.resize(12);
int t;
try {
    t = v[12];
} catch(std::exception  e){
    std::cout<<"error:"<<e.what()<<"\n";
}
Run Code Online (Sandbox Code Playgroud)

c++ stl

6
推荐指数
2
解决办法
2982
查看次数

超出 C++ 的界限和未定义的行为

我知道在 C++ 中访问缓冲区边界是未定义的行为。
这是来自 cppreference 的示例:

int table[4] = {};
bool exists_in_table(int v)
{
    // return true in one of the first 4 iterations or UB due to out-of-bounds access
    for (int i = 0; i <= 4; i++) {
        if (table[i] == v) return true;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

但是,我在 c++ 标准中找不到相应的段落。
谁能指出我在标准中解释这种情况的具体段落?

c++ undefined-behavior language-lawyer

6
推荐指数
1
解决办法
240
查看次数

匹配的C样式数组通过GMock作为void *传递

我正在尝试模拟这样的功能:

int write(int fd, const void* buffer, size_t size, bool something)
Run Code Online (Sandbox Code Playgroud)

我想检查通过缓冲区传递的数据的正确性(第一个和最后一个参数对测试不重要)。很少有匹配器可以帮助我们完成这些任务,即ElementsAreArray。如果指针是eg char*,那么很简单:

EXPECT_CALL(myMock, write(_, NotNull(), expectedSize, _)
    .With(Args<1,2>(ElementsAreArray(dummyArray));
Run Code Online (Sandbox Code Playgroud)

问题:void *无法取消引用。因此,它不能与ElementsAreArray匹配。

我尝试了以下方法:

EXPECT_CALL(myMock, write(_, NotNull(), expectedSize, _)
    .With(Args<1,2>(MatcherCast<::testing::tuple<const char*, size_t>>(ElementsAreArray(dummyArray)));
Run Code Online (Sandbox Code Playgroud)

但在MatcherCast中无法通过static_assert- T_must_be_implicitly_convertible_to_U

可以编写自己的匹配器来避免这种情况,但是感觉很笨拙。下面的一个有效,但我更希望避免编写自己的匹配器:

MATCHER_P2(EqualToArray, compareArray, n, "")
{
    const char *arr = static_cast<const char*>(arg);
    for (size_t i = 0; i < n; ++i)
    {
        if (arr[i] != compareArray[i])
        {
            return false;
        }
    }
    return true;
}

EXPECT_CALL(myMock, write(_, EqualToArray(dummyArray, expectedSize), expectedSize, _);
Run Code Online (Sandbox Code Playgroud)

编辑:对不起,我可能还没有说清楚。
我知道从void *转换为任何其他指针类型的问题不大。但这要求我们拥有一个功能或用户定义的匹配器,例如与我编写的功能或用户定义的匹配器,如果可能的话,我试图避免使用用户定义的匹配器,如果可能的话,可以使用已经定义的GMock匹配器。

因此,更具体的问题是:
是否可以强制 void* …

c++ gmock

5
推荐指数
1
解决办法
554
查看次数

仅与类的其他对象进行比较时,是否有任何理由不重载operator ==作为成员?

我一直在梳理互联网以找到答案,但找不到任何答案。给出的唯一原因似乎与比较不同类型的对象(例如MyClass == int)有关。但是最常见的用例是将一个类实例与同一类的另一个实例进行比较,而不是与任何不相关的类型进行比较。

换句话说,我确实了解以下问题:

struct A {
    bool operator==(int b);
};
Run Code Online (Sandbox Code Playgroud)

但是我找不到最明显的用例不使用成员函数的任何充分理由:

struct A {
    bool operator==(const A&);
};
Run Code Online (Sandbox Code Playgroud)

另一方面,成员超载似乎有几个积极方面:

  • 无需成为函数的朋友或为成员提供获取器
  • 它始终可供班级用户使用(尽管这也可能是不利的一面)
  • 查找没有问题(出于某种原因,这在我们的GoogleTests中似乎很常见)

将重载operator==作为非成员函数仅仅是为了保持其与其他类中可能的重载相同的约定?还是有其他原因使其成为非会员?

c++ operator-overloading

5
推荐指数
2
解决办法
128
查看次数

您可以修改 VS Code for C++ 中的“创建定义”模板以使用命名空间块而不是顶级的完全限定定义吗?

假设我写了一个新课程。我从标题开始MyClass.hpp

#pragma once

namespace MyProjectNamespace {
class MyClass {
public:
    foo(int i);
};
}
Run Code Online (Sandbox Code Playgroud)

目前还没有相应的 .cpp 文件,但 C++ 扩展有一个很好的快速修复来解决它 - 我可以Ctrl+.并选择“在 MyClass.cpp 中创建 'foo' 的定义”。这将创建一个MyClass.cpp如下文件:

#include "MyClass.hpp"

MyProjectNamespace::MyClass::foo(int i)
{
}
Run Code Online (Sandbox Code Playgroud)

但是,正如您所看到的,这在定义中使用(几乎)完全限定名称,而不是像在标头中那样打开名称空间。我可以自己修复它,任何进一步的“创建定义”操作都会将其正确放置在命名空间内,但对于新文件来说仍然有点烦人。

是否可以通过设置更改此操作的行为或以某种方式修改扩展使用的模板以始终在新定义上打开命名空间(如果不存在)?

c++ visual-studio-code

5
推荐指数
1
解决办法
58
查看次数

C++中静态变量的存储位置是什么时候确定的?

我有以下简单的程序:

int main()
{
    int x = 5;
    static int y = x;
    return (0);
}
Run Code Online (Sandbox Code Playgroud)

用 gcc 编译它,它会产生该行的错误,static int y = x;因为“初始化元素不是常量”。我认为这是由于它y是一个静态变量,在编译时需要知道其存储位置(数据/bss)和初始值。

但是,当使用 g++ 编译时,我没有收到任何错误并且程序运行良好(y打印出 5 个)。

我的问题是:

  1. 我的假设正确吗?
  2. 如果是这样,为什么可以在 C++ 中对静态变量进行这样的初始化?

c c++ build static-variables

4
推荐指数
2
解决办法
105
查看次数