显然std::function::operator=(F &&f)是需要的行为完全一样std::function(std::forward<F>(f)).swap(*this);.
除非我遗漏了某些东西,否则这个定义会导致一些多余的移动:
#include <functional>
#include <iostream>
struct A
{
A() {std::cout << "A()\n";}
A(const A &) {std::cout << "A(const A &)\n";}
A(A &&) {std::cout << "A(A &&)\n";}
A &operator=(const A &) {std::cout << "A &operator=(const A &)\n"; return *this;}
A &operator=(A &&) {std::cout << "A &operator=(A &&)\n"; return *this;}
~A() {std::cout << "~A()\n";}
void operator()() const {}
};
int main()
{
std::function<void()> f;
f = A{};
}
Run Code Online (Sandbox Code Playgroud)
打印:
Run Code Online (Sandbox Code Playgroud)A() // Created by `A{}` …
我正在尝试学习一些神秘的有状态模板元编程技巧。
(这就是我想学习它的原因。不幸的是,这个库在 GCC 8 和 Clang 上都不起作用。)
我需要的第一个明显的东西是一个constexpr计数器:
/*something*/ constexpr int foo() /*something*/
int main()
{
constexpr int a = foo();
constexpr int b = foo();
constexpr int c = foo();
static_assert(a == 0 && b == 1 && c == 2);
}
Run Code Online (Sandbox Code Playgroud)
最好它应该是一个标记的计数器,以便我可以同时拥有多个计数器:
/*something*/ constexpr int foo() /*something*/
struct TagA {};
struct TagB {};
int main()
{
constexpr int a = foo<TagA>();
constexpr int b = foo<TagA>();
constexpr int c = foo<TagA>();
constexpr …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Clang的“模块”功能,并且正在尝试编译以下代码:
export module a;
#include <new>
export void *foo()
{
return ::operator new(1, std::align_val_t(1));
}
export int main() {}
Run Code Online (Sandbox Code Playgroud)
当我尝试时clang++ -std=c++2a -pedantic-errors -fmodules-ts --precompile -x c++-module a.cpp -o a.pcm,我得到了
Run Code Online (Sandbox Code Playgroud)error: ISO C++ requires a definition in this translation unit for function 'operator new' because its type does not have linkage [-Werror,-Wundefined-internal-type] a.cpp:7:14: note: used here return ::operator new(1, std::align_val_t(1)); ^ 1 error generated.
删除-pedantic-errors修复了该错误,但是当我尝试使用链接生成的模块时clang++ -std=c++2a -fmodules-ts a.pcm -o a.exe,我得到了
Run Code Online (Sandbox Code Playgroud)Z:\Lander\msys2\tmp\a-cfaf65.o:a.pcm:(.text+0x10): undefined …
随着即将推出的 C++20 标准,我们将拥有可供使用的协程。基于协程调试代码的最佳方法是什么?可以做什么来追踪呼叫流程?
如何以正确的方式比较整数和浮点值?
内置比较运算符在某些情况下会给出错误的结果,例如:
#include <iomanip>
#include <iostream>
int main()
{
long long a = 999999984306749439;
float b = 999999984306749440.f; // This number can be represented exactly by a `float`.
std::cout << std::setprecision(1000);
std::cout << a << " < " << b << " = " << (a < b) << '\n';
// Prints `999999984306749439 < 999999984306749440 = 0`, but it should be `1`.
}
Run Code Online (Sandbox Code Playgroud)
显然,比较运算符在实际比较它们之前将两个操作数都转换为相同类型。在这里,lhs转换为float,这会导致精度损失,并导致错误的结果。
即使我了解发生了什么,也不确定如何解决此问题。
免责声明:该示例使用float和long long,但我正在寻找一种通用解决方案,该解决方案适用于整数类型和浮点类型的每种组合。
请原谅这个令人费解的标题,并考虑以下代码:
#include <memory>
#include <utility>
using X = std::unique_ptr<int>;
using A = std::pair<int, const X>;
using B = std::pair<int, X>;
static_assert(std::is_constructible<A, B>::value, "(1)"); // Ok.
static_assert(std::is_convertible<B, A>::value, "(2)"); // Rejected by GCC and Clang, in C++14 and before.
static_assert(std::is_constructible<const X, X>::value, "(3)"); // Ok.
static_assert(std::is_convertible<X, const X>::value, "(4)"); // Ok.
Run Code Online (Sandbox Code Playgroud)
简而言之,std::pair<int, const std::unique_ptr<int>>来自类型右值的构造函数std::pair<int, std::unique_ptr<int>>在explicitC++14、隐式和 C++17 及更新版本中。这种差异从何而来?
只有 libstdc++ 和 libc++ 演示了此行为。在MSVC的库中,构造函数总是隐式的。
为什么是explicit在 C++14 中?我没有看到任何与cppreference(构造函数(6))相关的内容。
根据 cppreference,std::move_iterator将其设置为其基础迭代器1::iterator_category的类别。
但我认为它最多可以是一个输入/输出迭代器,因为对于前向迭代器 reference来说必须是左值引用,而move_iterator设置reference(以及 的返回类型operator*)为右值引用2。
这是迭代器公然错误地标记了错误的类别吗?
能够为我自己的迭代器执行此操作无疑很方便。如果标准库也这样做的话,我有什么理由不应该这样做吗?
1但是任何比 强的东西random_access_iterator_tag都会被截断为random_access_iterator_tag,这很奇怪,因为contiguous_iterator_tag它只应该用于::iterator_concept。
2或者,如果它不是引用,则保持不变,但底层迭代器也不应该将自己宣传为前向迭代器。
为什么下面的C++代码无法编译?
#include <utility>
int main() {
int x[6];
int y[6];
std::pair<int[6], int[6]> a(x, y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
例如 MSVC 给出以下错误:
错误 C2661: 'std::pair<int [6],int [6]>::pair': 没有重载函数需要 2 个参数
感谢使用C++替代品构造数组的评论,但我也想知道代码无法编译的原因。
在我正在编写的程序中,我的 .h 文件中目前有几个未初始化的变量,所有这些变量都在运行时初始化。但是,在 Visual Studio 中,每次我执行此操作时它都会警告我“始终初始化成员变量”,尽管这样做似乎毫无意义。我很清楚在未初始化时尝试使用变量会导致未定义的行为,但据我所知,不这样做可以避免这种情况。我是否忽略了什么?
谢谢。