标签: cpp-core-guidelines

地图、集合等的 array_view 替代方案

假设我有一些类层次结构,其中有几个virtual函数返回容器引用:

#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>

class Interface {
public:
    virtual const std::vector<int>& getArray() const = 0;
    virtual const std::set<int>& getSet() const = 0;
    virtual const std::map<int, int>& getMap() const = 0;
};

class SubclassA : public Interface {
public:
    const std::vector<int>& getArray() const override { return _vector; }
    const std::set<int>& getSet() const override { return _set; }
    const std::map<int, int>& getMap() const override { return _map; }

private:
    std::vector<int> _vector;
    std::set<int> _set; …
Run Code Online (Sandbox Code Playgroud)

c++ c++11 c++14 array-view cpp-core-guidelines

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

如何使用 gsl::span 并指示所有权?

我想写一个函数:

  1. 接受一个指针作为参数
  2. 以长度作为参数
  3. 拥有指针指向的内存(例如,它可能会释放它,或者在某些数据结构中为其构造一个 unique_ptr 等)

现在,如果我想要 1+2,我就会使用gsl::span. 如果想要 1+3 我会使用owner<T*>. 但当我想要这三个时我该怎么办?我应该通过吗owner<gsl::span<T>>?还有别的事吗?

笔记:

  • 您可能不会假设指针位于堆中。
  • std::vector要求太多。该函数不应该要求调用者构造一个std::vector.

c++ cpp-core-guidelines guideline-support-library

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

我应该返回gsl :: span <const T>而不是const std :: vector <T>&

我有一个带有std :: vector <int>成员的类和一个返回对该向量的const引用的成员函数.

class demo {
public:
    //...

    const std::vector<int> & test() const {
        return iv;
    }

private:

    std::vector<int> iv;
};
Run Code Online (Sandbox Code Playgroud)

我计划将成员类型更改为不同的数组,如容器类型,具有足够的功能和更小的内存占用(例如std :: experimental :: dynarray,std :: unique_ptr <int []>).因此,我认为不将真实容器作为const引用返回,而是将视图作为gsl :: span <const int>返回给元素是个好主意.

class demo {
public:
    //...

    gsl::span<const int> test() const {
        return iv;
    }

private:

    std::vector<int> iv;
};
Run Code Online (Sandbox Code Playgroud)

但这会破坏使用const vector <int>的代码,因为同一个未修改的向量的两个span实例不能用于迭代元素:

demo d;

std::cout << (d.test().begin() == d.test().begin()) << "\n";
std::cout << (d.test().end() == d.test().end()) << "\n";

for( auto it = d.test().begin(), end = d.test().end(); it …
Run Code Online (Sandbox Code Playgroud)

c++ cpp-core-guidelines guideline-support-library

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

`gsl::string_span` 的目的是什么?

在阅读Microsoft's implementation of Cpp Core Guidelines 时,我遇到了两个问题:

  1. 为什么gsl::string_spangsl::span已经运行良好的地方提供?
  2. 为什么gsl::zstring_spanstd::string自 C++11 以来已保证以空值终止的地方提供?

任何说明情况都将受到高度赞赏。

c++ library-design c++11 cpp-core-guidelines

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

std::span.size() 与数组/向量大小

我们正在工作中尝试std::span()(目前使用 gsl 实现)。最近我们发现将 astd::span.size()与 a进行比较vector.size()会得到 a -Wsign-compare error

if( span.size() > vector.size() ) // comparison between signed and unsigned integer expressions [-Wsign-compare]
Run Code Online (Sandbox Code Playgroud)

我认为我们不想对每一项比较都进行选角。我们的编码指南将这些警告视为错误。好奇是否有人有任何想法或建议?

c++ cpp-core-guidelines

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

CMake与Visual Studio 2017 C ++核心准则检查器(CppCoreCheck)的集成

我目前尝试使用生成器将Visual Studio 2017 的C ++核心准则检查器(CppCoreCheck)与元生成系统CMake集成在一起Visual Studio 15 2017 Win64

以下示例说明了我的方法(我尝试将CMake源代码精简到最小)。

首先,我将所有编译器开关添加到了构建目标,以使用CppCoreCheck进行分析:

cmake_minimum_required(VERSION 3.12)

project(cppcorecheck-example)

find_package(Boost REQUIRED MODULE)

add_executable(app main.cpp)
target_link_libraries(app PRIVATE Boost::boost)
target_compile_options(app
    PRIVATE
    "/analyze"
    "/analyze:WX-"
    "/analyze:log" "cppcorecheck.xml"
    "/analyze:stacksize" 16384
    "/analyze:max_paths" 256
    "/analyze:ruleset" "CppCoreCheckRules.ruleset"
    "/analyze:plugin EspXEngine.dll"
    )
Run Code Online (Sandbox Code Playgroud)

我正在使用以下内容main.cpp

#include <boost/system/error_code.hpp>

int main() {
  int arr[10];   // warning C26494
  int* p = arr;  // warning C26485

  {
    int* q = p + 1;  // warning C26481
    p = q++;         // warning C26481
  } …
Run Code Online (Sandbox Code Playgroud)

c++ cmake visual-studio static-code-analysis cpp-core-guidelines

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

不要使用静态转换进行算术转换(cpp-core-guidelines)

msvc 的 cpp 核心指南代码分析器告诉我

警告 C26472 不要使用 astatic_cast进行算术转换。使用大括号初始化,gsl::narrow_castgsl::narrow (type.1)。

对于这个片段

static_cast<IntType>(static_cast<unsigned long long>(hexValue(digit)) << (digitIdx * 4));
Run Code Online (Sandbox Code Playgroud)

为什么我不应该在这里使用 static_cast ?

另外,使用大括号初始化,这看起来像这样

IntType{unsigned long long{hexValue(digit)} << (digitIdx * 4)};
Run Code Online (Sandbox Code Playgroud)

我认为这看起来并没有更好。这看起来更像是函数风格的转换而不是其他任何东西。

我无法使用 gsl 并且我认为gsl::narrow它是自身的包装器static_cast,所以这纯粹是一个可读性问题吗?

c++ cpp-core-guidelines

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

C++ 警告:将新创建的 gsl::owner&lt;&gt; 分配给非所有者

当我使用以下代码时,我收到一条警告(来自应用 cppcoreguideline)。代码:

 SampleClass *object = nullptr;
 object = new SampleClass();
Run Code Online (Sandbox Code Playgroud)

警告:

 warning: assigning newly created 'gsl::owner<>' to non-owner 'SampleClass *' [cppcoreguidelines-owning-memory]
Run Code Online (Sandbox Code Playgroud)

当我搜索并访问此链接时 https://releases.llvm.org/8.0.1/tools/clang/tools/extra/docs/clang-tidy/checks/cppcoreguidelines-owning-memory.html

我无法理解,有人可以用简单的术语解释一下。

c++ cpp-core-guidelines

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

在 C++ Core Guidelines Per.4 中,为什么坏示例旨在更快?

我最近正在阅读这篇文章,其中指出:

不要认为复杂的代码一定比简单的代码快。

代码复制如下:

例子,不错

// clear expression of intent, fast execution

vector<uint8_t> v(100000);

for (auto& c : v)
    c = ~c;
Run Code Online (Sandbox Code Playgroud)

例子,坏

// intended to be faster, but is often slower

vector<uint8_t> v(100000);

for (size_t i = 0; i < v.size(); i += sizeof(uint64_t)) {
    uint64_t& quad_word = *reinterpret_cast<uint64_t*>(&v[i]);
    quad_word = ~quad_word;
}
Run Code Online (Sandbox Code Playgroud)

我不确定坏例子的目的是什么,为什么它打算更快
为什么它实际上通常更慢

c++ performance cpp-core-guidelines

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

如何正确使用“C++ 核心指南:C.146:在不可避免的类层次结构导航中使用 dynamic_cast”

动机

C++ 核心指南建议dynamic_cast在“类层次结构导航不可避免”时使用。这触发铛,整洁抛出以下错误:Do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]

指导方针继续说:

注意

像其他演员一样,dynamic_cast被过度使用。更喜欢virtual函数而不是铸造。在可能的情况下(不需要运行时解析)并且相当方便,更喜欢静态多态性而不是层次结构导航。

我一直只使用嵌套在我的基类中的enum命名Kind,并static_cast根据其类型执行 a 。阅读 C++ 核心指南,“...即便如此,根据我们的经验,诸如“我知道我在做什么”的情况仍然是一个已知的错误来源。” 建议我不应该这样做。通常,我没有任何virtual函数,所以 RTTI 不存在使用dynamic_cast(例如,我会得到error: 'Base_discr' is not polymorphic)。我总是可以添加一个virtual函数,但这听起来很傻。该指南还说在考虑使用我使用的判别方法之前先进行基准测试Kind

基准


enum class Kind : unsigned char {
    A,
    B,
};


class Base_virt {
public:
    Base_virt(Kind p_kind) noexcept : m_kind{p_kind}, m_x{} …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism dynamic-cast static-polymorphism cpp-core-guidelines

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