小编Nar*_*yan的帖子

为什么在2个不同的cpp文件中定义内联全局函数会产生神奇的结果?

假设我有两个.cpp文件file1.cppfile2.cpp:

// file1.cpp
#include <iostream>

inline void foo()
{
    std::cout << "f1\n";
}

void f1()
{
    foo();
}
Run Code Online (Sandbox Code Playgroud)

// file2.cpp
#include <iostream>

inline void foo()
{
   std::cout << "f2\n";
}

void f2()
{
    foo();
}
Run Code Online (Sandbox Code Playgroud)

main.cpp我已经向前宣布f1()f2():

void f1();
void f2();

int main()
{
    f1();
    f2();
}
Run Code Online (Sandbox Code Playgroud)

结果(不依赖于构建,调试/发布版本的结果相同):

f1
f1
Run Code Online (Sandbox Code Playgroud)

哇:编译器以某种方式仅选择定义file1.cpp并在其中使用它f2().这种行为的确切解释是什么?

注意,改变inlinestatic是这个问题的解决方案.将内联定义放在未命名的命名空间中也可以解决问题并且程序打印:

f1
f2
Run Code Online (Sandbox Code Playgroud)

c++ inline translation-unit

30
推荐指数
3
解决办法
3141
查看次数

C++类型转换.static_cast何时成功并且reinterpret_cast会导致问题?

我理解a static_cast是一种从一种类型到另一种类型的演员,(直觉上)是一种演员,在某些情况下可以成功并且在没有危险演员的情况下有意义.同时,a reinterpret_cast是一个表示不安全转换的转换,它可能将一个值的位重新解释为另一个值的位.

当代码编译,转换并且static_cast不会引起任何问题时,有人可以描述一个场景,但是reinterpret_cast会出现问题吗?

c++ casting

24
推荐指数
3
解决办法
1625
查看次数

为什么这些矩阵换位时间如此反直觉?

以下示例代码生成一个size的矩阵N,并将其转换SAMPLES次数.当N = 512转置操作的平均执行时间是2144 ?s(coliru链接)时.乍一看,没有什么特别的,对吗?...

好吧,这是结果

  • N = 5131451 ?s
  • N = 519600 ?s
  • N = 530486 ?s
  • N = 540492 ?s(终于!理论开始工作:).

那么为什么在实践中这些简单的计算与理论如此不同呢?此行为是否与CPU缓存一致性或缓存未命中有关?如果是这样请解释.

#include <algorithm>
#include <iostream>
#include <chrono>

constexpr int N       = 512; // Why is 512 specifically slower (as of 2016)
constexpr int SAMPLES = 1000;
using us = std::chrono::microseconds;

int A[N][N];

void transpose()
{
    for ( int i = …
Run Code Online (Sandbox Code Playgroud)

c++ performance matrix low-latency cpu-cache

12
推荐指数
1
解决办法
399
查看次数

C++ Copy构造函数+指针对象

我正在努力学习C++中的"三巨头"..我设法为"三巨头"做了非常简单的程序..但我不知道如何使用对象指针..以下是我的第一次尝试.

当我写这篇文章时,我有一个疑问......

问题

  1. 这是实现默认构造函数的正确方法吗?我不确定我是否需要它.但是我在另一个关于带有指针的复制构造函数的线程中发现的是我需要在复制构造函数中复制地址之前为该指针分配空间.
  2. 如何在复制构造函数中分配指针变量?我在Copy Constructor中编写的方式可能有误.
  3. 我是否需要为复制构造函数和operatior =实现相同的代码(返回除外)?
  4. 我是否正确地说我需要删除析构函数中的指针?

    class TreeNode
    {
    public:  
       TreeNode(); 
       TreeNode(const TreeNode& node);
       TreeNode& operator= (const TreeNode& node);
       ~TreeNode();
    private:
       string data;
       TreeNode* left;
       TreeNode* right;
       friend class MyAnotherClass;
    };
    
    Run Code Online (Sandbox Code Playgroud)

履行

TreeNode::TreeNode(){

    data = "";  

}

TreeNode::TreeNode(const TreeNode& node){
     data = node.data;

     left = new TreeNode();
     right = new TreeNode();

     left = node.left; 
     right = node.right;
}

TreeNode& TreeNode::operator= (const TreeNode& node){
     data = node.data;
     left = node.left;
     right = node.right;
     return *this;
}

TreeNode::~TreeNode(){
     delete …
Run Code Online (Sandbox Code Playgroud)

c++ rule-of-three

8
推荐指数
2
解决办法
1万
查看次数

在这种情况下如何避免代码重复问题?

我有两个类似的功能,即使用图形节点或边缘进行一些计算.

void foo(const VertexMgr& mgr, const std::string name)
{
    // Skipped..
    for (int i = 0; i< 100; ++i)
    {
        // Skipped
        const A& a = CreateSomething();
        for (IterType<Vertex> it = a->vertices(); it != NULL(); ++it)
        {
            // do something
        }
    }
}

void goo(const EdgeMgr& mgr, const std::string& name)
{
    // Skipped..
    for (int i = 0; i< 100; ++i)
    {
        // Skipped
        const A& a = CreateSomething();
        for (IterType<Edge> it = a->edges(); it != NULL(); ++it)
        {
            // …
Run Code Online (Sandbox Code Playgroud)

c++

8
推荐指数
1
解决办法
176
查看次数

C++如何强制预取数据缓存?(数组循环)

我有这样的循环

start = __rdtsc();
unsigned long long count = 0;
for(int i = 0; i < N; i++)
    for(int j = 0; j < M; j++)
        count += tab[i][j];
stop = __rdtsc();
time = (stop - start) * 1/3;
Run Code Online (Sandbox Code Playgroud)

需要检查预取数据如何影响效率.如何在计算之前强制从内存中预取一些值到缓存中?

c++ prefetch cpu-cache

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

在prolog中检测所有k长度的字符串

单词是由空格或字符串的起点/终点分隔的任何符号字符.对于前者 [w,o,r,d,1,' ',w,o,r,d,2].

我需要找到给定字符串的所有k长度单词并将它们附加到结果字符串中(用空格分隔).这就是我期望的例子,例如在k = 5的情况下:

?- kthWords([w,o,r,d,1,'',w,r,d,'',w,o,r,d,2], 5, X).
X = [w,o,r,d,1,'',w,o,r,d,2].
Run Code Online (Sandbox Code Playgroud)

string recursion prolog

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

软件预取手动指令的情况是合理的

我在x86和x86-64上已经了解到这一点,英特尔gcc提供了特殊的预取指令:

#include <xmmintrin.h>
enum _mm_hint
{
_MM_HINT_T0 = 3,
_MM_HINT_T1 = 2,
_MM_HINT_T2 = 1,
_MM_HINT_NTA = 0
};
void _mm_prefetch(void *p, enum _mm_hint h);
Run Code Online (Sandbox Code Playgroud)

程序可以_mm_prefetch在程序中的任何指针上使用内在函数.并且与_mm_prefetch 内在函数一起使用的不同提示是实现定义的.一般来说,每个提示都有其自身的含义.

_MM_HINT_T0将 数据提取到包含高速缓存的所有高速缓存级别以及用于独占高速缓存的最低级别高速缓存

_MM_HINT_T1提示将数据拉入L2而不是L1d.如果有一个L3缓存,_MM_HINT_T2 提示可以为它做类似的事情

_MM_HINT_NTA,允许告诉处理器专门处理预取的缓存行

那么当有人使用这条指令时,有人会描述一些例

以及如何正确选择提示?

c++ gcc prefetch cpu-cache

3
推荐指数
1
解决办法
727
查看次数

解析器(TCL)中的换行符支持

所以,我有一个用TCL编写的解析器.解析文件中有许多命令.现在,我需要添加对换行符的支持.对于前者

my_command \
  arg1 \
  arg2 \
  arg3 
Run Code Online (Sandbox Code Playgroud)

我有类似的东西.

while { ! [eof $currentFileDescriptor] } {
            set line [gets $currentFileDescriptor]
            set lst [lindex [regexp -all -inline {^(\s*(\S*)\s*)*(\{(.*)\})?(\s*(\S*)\s*)*$} $line] 0]
            set tok [string toupper [lindex $lst 0]]
            switch -glob $tok {
              "\#*" { }
              "MY_COMMAND_1" { parseMyCommand1 $handler $lst }
              .....#other commands  }
            }
            incr lnum
        }
Run Code Online (Sandbox Code Playgroud)

我正在寻找一个最佳和有效的解决方案.

parsing tcl

0
推荐指数
1
解决办法
96
查看次数