所以我正在尝试使用LLVM构建一个玩具编译器,我想使用CMake作为我的构建系统.我尝试使用LLVM网站上的示例CMakeLists.txt,但运行时遇到以下错误cmake
:
CMake Error at /usr/share/llvm-3.8/cmake/LLVMConfig.cmake:178 (include):
include could not find load file:
/usr/share/llvm/cmake/LLVMExports.cmake
Call Stack (most recent call first):
CMakeLists.txt:4 (find_package)
CMake Error at /usr/share/llvm-3.8/cmake/LLVMConfig.cmake:181 (include):
include could not find load file:
/usr/share/llvm/cmake/LLVM-Config.cmake
Call Stack (most recent call first):
CMakeLists.txt:4 (find_package)
Run Code Online (Sandbox Code Playgroud)
当我去调查问题时,我发现我的系统上的路径实际上是/usr/share/llvm-3.8/
.当我尝试将路径更改为/usr/share/llvm/
预期时,我收到另一个错误:
CMake Error at /usr/share/llvm/cmake/LLVMExports.cmake:1034 (message):
The imported target "LLVMSupport" references the file
"/usr/lib/libLLVMSupport.a"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved …
Run Code Online (Sandbox Code Playgroud) 在 C++ 中构造单文件/仅标头库,以便它们有条件地成为标头或实现,这是否被认为是良好实践?例如,
#ifndef LIBRARY_HEADER_HPP_
#define LIBRARY_HEADER_HPP_
// Header
struct Test {
void test();
};
#endif // LIBRARY_HEADER_HPP_
#ifdef LIBRARY_IMPLEMENTATION_
#undef LIBRARY_IMPLEMENTATION_
// Implementation
void Test::test() {
}
#endif // LIBRARY_IMPLEMENTATION_
Run Code Online (Sandbox Code Playgroud)
因此,库的用户将#define LIBRARY_IMPLEMENTATION
在单个 #include "Library.hpp"
实现文件中使用一个定义,以避免多个定义。
我已经在 C 库中看到过这种策略(想到了STB),但我想知道这在现代 C++ 中是否被认为是惯用的(或者是否有更好的策略来创建单文件/仅头文件库)。
我最近决定.clang-format
在我的 C++ 项目中包含一个文件,以使代码更加统一和易于阅读。我最喜欢谷歌的默认设置,除了我想使用 4 个空格缩进而不是两个。
这样做的问题是当当前行超出 80 个字符的列限制时,它会使某些语句更难阅读。例如,在溢出的 if 语句中:
if (some_condition || some_other_condition ||
yet_another_condition) {
// block starts here
}
Run Code Online (Sandbox Code Playgroud)
对齐方式yet_another_condition
与 if 块开头的对齐方式相匹配,这使得在没有某种中断的情况下很难阅读。理想情况下,我希望在这种情况下发生的事情是这样的:
if (some_condition || some_other_condition ||
yet_another_condition)
{
// block starts here
}
Run Code Online (Sandbox Code Playgroud)
但是,当当前行溢出到下一行时,我只希望在新行上打开大括号,就像上面的例子一样。在所有其他情况下,我希望左括号在同一行上(这适用于 if/for/while/switch 等语句以及函数)。
是否可以在我的.clang-format
文件中指定此行为,同时保持其余 Google 默认值不变?
因此,我对移动语义的理解是,它们允许您覆盖用于临时值(rvalues)的函数,并避免可能昂贵的副本(通过将状态从未命名的临时值移动到命名的左值).
我的问题是为什么我们需要特殊的语义?为什么C++ 98编译器不能忽略这些副本,因为编译器确定给定表达式是左值还是左值?举个例子:
void func(const std::string& s) {
// Do something with s
}
int main() {
func(std::string("abc") + std::string("def"));
}
Run Code Online (Sandbox Code Playgroud)
即使没有C++ 11的移动语义,编译器仍应能够确定传递给它的表达式func()
是否是rvalue,因此不需要临时对象的副本.那为什么要有这个区别呢?似乎移动语义的这种应用本质上是复制省略或其他类似编译器优化的变体.
作为另一个例子,为什么要打扰如下代码呢?
void func(const std::string& s) {
// Do something with lvalue string
}
void func(std::string&& s) {
// Do something with rvalue string
}
int main() {
std::string s("abc");
// Presumably calls func(const std::string&) overload
func(s);
// Presumably calls func(std::string&&) overload
func(std::string("abc") + std::string("def"));
}
Run Code Online (Sandbox Code Playgroud)
似乎const std::string&
重载可以处理这两种情况:lvalues像往常一样,rvalues作为const引用(因为临时表达式按照定义是const类).由于编译器知道表达式何时是左值或右值,因此可以决定是否在rvalue的情况下忽略副本.
基本上,为什么移动语义被认为是特殊的,而不仅仅是一个可以由前C++ 11编译器执行的编译器优化?
在看了Titus Winters的"Live at Head"演讲后,他提到StrCat()是人们最喜欢的功能之一,我决定尝试实现类似的东西,看看我是否能击败std :: string :: append(或operator +) ,在运行时性能方面,我认为在内部使用附加.我的理由是,作为可变参数模板实现的strcat()函数将能够确定其所有类似字符串的参数的组合大小,并进行单个分配以存储最终结果,而不必在以下情况下不断重新分配: operator +,它不知道它所调用的总体上下文.
但是,当我在快速工作台上将我的自定义实现与operator +进行比较时,我发现我的strcat()实现比clang和gcc的最新版本的运算符+慢了4倍-std=c++17 -O3
.我在下面提供了快速工作台代码供参考.
有谁知道这会导致减速的原因是什么?
#include <cstring>
#include <iostream>
#include <string>
// Get the size of string-like args
int getsize(const std::string& s) { return s.size(); }
int getsize(const char* s) { return strlen(s); }
template <typename S>
int strcat_size(const S& s) {
return getsize(s);
}
template <typename S, typename... Strings>
int strcat_size(const S& first, Strings... rest) {
if (sizeof...(Strings) == 0) {
return …
Run Code Online (Sandbox Code Playgroud) 我尝试按照官方文档在外部内容表中使用 SQLite 的全文搜索 (FTS) 扩展。我正在运行 Arch linux 软件包中的 sqlite 版本 3.42.0 sqlite
,当前版本为 3.42.0-1。
架构如下:
-- Create main data table
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
-- Create fts index table
CREATE VIRTUAL TABLE users_fts USING fts5 (
content='users',
content_rowid='id',
name
);
-- Create insert trigger
CREATE TRIGGER users_fts_insert AFTER INSERT ON users
BEGIN
INSERT INTO users_fts (rowid, name) VALUES (new.rowid, new.name);
END;
-- Insert some sample data
INSERT INTO users (rowid, …
Run Code Online (Sandbox Code Playgroud) 我正在尝试合并两个向量unique_ptr
(即std::move
它们从一个到另一个),并且我继续遇到"使用已删除的函数..."错误文本的墙.根据错误,我显然试图使用unique_ptr
已删除的复制构造函数,但我不确定原因.以下是代码:
#include <vector>
#include <memory>
#include <algorithm>
#include <iterator>
struct Foo {
int f;
Foo(int f) : f(f) {}
};
struct Wrapper {
std::vector<std::unique_ptr<Foo>> foos;
void add(std::unique_ptr<Foo> foo) {
foos.push_back(std::move(foo));
}
void add_all(const Wrapper& other) {
foos.reserve(foos.size() + other.foos.size());
// This is the offending line
std::move(other.foos.begin(),
other.foos.end(),
std::back_inserter(foos));
}
};
int main() {
Wrapper w1;
Wrapper w2;
std::unique_ptr<Foo> foo1(new Foo(1));
std::unique_ptr<Foo> foo2(new Foo(2));
w1.add(std::move(foo1));
w2.add(std::move(foo2));
return 0;
}
Run Code Online (Sandbox Code Playgroud) c++ ×6
c++11 ×3
abseil ×1
benchmarking ×1
clang-format ×1
cmake ×1
copy-elision ×1
curly-braces ×1
formatting ×1
header-only ×1
llvm ×1
performance ×1
sql ×1
sqlite ×1
triggers ×1
ubuntu ×1
unique-ptr ×1