0%

C++支持可变模版参数

1
template <typename... Args> void foo(Args... args);

std::call_once准确执行一次可调用 (Callable) 对象 f ,即使同时从多个线程调用。

有时候为了方便会把std::once_flag声明在函数内中,比如说

1
2
3
4
5
void callOne() {
static std::once_flag flag;
std::call_once(flag, []() { // do something});
});
}

但是和可变模版参数结合在一起就一些看起来神奇的特性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static int counter{0};

template <typename... Args> void test(Args... args) {
static std::once_flag flag;
static int calls{0};
std::call_once(flag, [&]() {
std::cout << "counter:" << ++counter << " call_once_times:" << ++calls
<< std::endl;
});
}

int main() {
test();
test(1);
}

可以发现有两行输出

1
2
counter:1 call_once_times:1
counter:2 call_once_times:1

这应该是模版展开了,其实是两个不同的函数了。解决方法也很简单,把flag变量往上提即可。

问题的发现

写单例模式时,类似于这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <mutex>
#include <utility>

template <typename T> class Singleton {
public:
template <typename... Args> static T *getInstance(Args... args);

private:
static inline T *instance{nullptr};
};

template <typename T>
template <typename... Args>
T *Singleton<T>::getInstance(Args... args) {
static std::once_flag flag;
std::call_once(flag,
[&]() { instance = new T(std::forward<Args>(args)...); });

return instance;
};

int main() {
Singleton<int>::getInstance(1);
Singleton<int>::getInstance();
}

第二次会得到一个新的实例。问题就出在static std::once_flag flag不应该在函数体中定义,应该在类中声明定义。

Focus on programming techniques, not on language features.

基于c++17标准
快速入门CS106L
阅读书籍笔记《A tour of C++》,《Beginning C++17》

阅读全文 »

没有解决,思路全错。可能就是网络问题。

错误描述

使用git通过SSH克隆远程仓库时,出现错误

ssh_dispatch_run_fatal: Connection to 20.205.243.166 port 22: Operation timed out
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

我记得我是有私钥的,做个测试。

1
ssh ssh -T [email protected]

报错

kex_exchange_identification: Connection closed by remote host
Connection closed by 20.205.243.166 port 22

阅读全文 »

CMake Help
系列基于CMake Tutorial
本文基于Step 4: Adding Generator Expressions

生成器表达式的值在构建(build)阶段才能得到。生成器表达式可用于根据某些条件设置某些变量和编译选项。
Generator expressions may be used to enable conditional linking, conditional definitions used when compiling, conditional include directories and more. The conditions may be based on the build configuration, target properties, platform information or any other queryable information.

阅读全文 »

CMake Help
系列基于CMake Tutorial
本文基于Step 2: Adding a Library
Rather than placing all of the source files in one directory, we can organize our project with one or more subdirectories. In this case, we will create a subdirectory specifically for our library. Here, we can add a new CMakeLists.txt file and one or more source files. In the top level CMakeLists.txt file, we will use the add_subdirectory() command to add the subdirectory to the build.
Once the library is created, it is connected to our executable target with target_include_directories() and target_link_libraries().

阅读全文 »