在en.cppreference的这一页上,有一些可能实现词典比较的例子.这是基本的:
template<class InputIt1, class InputIt2>
bool lexicographical_compare(InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2)
{
for ( ; (first1 != last1) && (first2 != last2); first1++, (void) first2++ ) {
if (*first1 < *first2) return true;
if (*first2 < *first1) return false;
}
return (first1 == last1) && (first2 != last2);
}
Run Code Online (Sandbox Code Playgroud)
类似于IIRC的行(void)some_argument;
通常用于抑制有关未使用参数的编译器警告.但是在这个函数中,使用了包括first2在内的所有参数 - 那么(void) first2++
在for语句中写入的重点是什么?
在InputIt1重载的情况下,它是一些语法解决方法operator,
吗?
我无法理解为什么第二个>>失败.我做错了什么或遗漏了一些代码?
std::ifstream file;
std::stringstream ss;
std::string str;
float f1, f2;
file.open("file.txt");
getline(file, str);
ss.str(str);
ss >> f1;
getline(file, str);//when packed inside if(), evalueates to true
ss.str(str);
ss >> f2; //when packed inside if(), evalueates to false - but why it fails?
std::cout<<"str = "<<str<<"\n";
std::cout<<"ss.str() = "<<ss.str()<<"\n";
std::cout<<"f1 = "<<f1<<"\nf2 = "<<f2<<"\n";
Run Code Online (Sandbox Code Playgroud)
文件:
0.120000
0.120000
Run Code Online (Sandbox Code Playgroud)
输出:
str = 0.120000
ss.str() = 0.120000
f1 = 0.12
f2 = 2.06831e+032
Run Code Online (Sandbox Code Playgroud)
我已经在多个文件上尝试了这个代码,显然只有第一次插入到float中,文件末尾有一个空行
编辑
正如Dan指出的那样,我尝试直接从文件中提取浮点数:
file.open("file.txt");
file >> f1;
file >> f2;
Run Code Online (Sandbox Code Playgroud)
理想的工作; 也简化了很多代码
在以下代码中,如果未注释移动分配,则交换函数将停止程序的编译。我在所有 3 个主要编译器(GCC、Clang、MSVC)上观察到了这种行为。
#include <utility>
#include <memory>
struct test
{
test() = default;
test(test&& other) noexcept = default;
//test& operator=(test&& other) noexcept = default;
test(const test& other)
: ptr(std::make_unique<int>(*other.ptr))
{}
test& operator=(test other) noexcept
{
std::swap(*this, other);
return *this;
}
std::unique_ptr<int> ptr;
};
Run Code Online (Sandbox Code Playgroud)
Godbolt 测试: https: //godbolt.org/z/v1hGzzEaz
研究标准库实现时,他们使用 SFINAE 或概念来启用/禁用std::swap
重载,并且当特殊函数未注释时,由于某种原因,某些特征会失败(is_move_constructible
和/或is_move_assignable
在 libstdc++ 上)。
我的问题是:为什么添加默认的特殊成员函数会阻止标准库将类型视为可移动?
T
编辑1:事实证明,问题在于 xvalues 在和之间的重载解析中没有偏好T&&
(这会导致不明确的重载错误),因此标准库特征无法将类型识别为可移动。
编辑 2:重要提示:请注意,示例代码不是复制和交换习惯用法的正确实现。应该使用自定义交换函数或使用所有 5 个特殊成员函数来完成。当前的实现创建了移动/复制分配和交换调用的无限递归。
首先,只是为了避免XY问题:此问题来自https://github.com/cnjinhao/nana/issues/445#issuecomment-502080177。库代码可能不应该这样做(依赖于未使用的全局对象的构造),但是问题更多的是关于它是否是有效的LTO行为,而不是代码质量问题。
展示相同问题的最小代码(未经试验,只是为了使示例更小):
// main.cpp
#include <lib/font.hpp>
int main()
{
lib::font f;
}
Run Code Online (Sandbox Code Playgroud)
// lib/font.hpp
namespace lib
{
struct font
{
font();
int font_id;
};
}
Run Code Online (Sandbox Code Playgroud)
// lib/font.cpp
#include <lib/font.hpp>
#include <lib/font_abstraction.hpp>
namespace lib
{
font::font()
{
font_id = get_default_font_id();
}
}
Run Code Online (Sandbox Code Playgroud)
// lib/font_abstraction.hpp
namespace lib
{
int get_default_font_id();
void initialize_font();
}
Run Code Online (Sandbox Code Playgroud)
// lib/font_abstraction.cpp
#include <lib/font_abstraction.hpp>
namespace lib
{
static int* default_font_id;
int get_default_font_id()
{
return *default_font_id;
}
void initialize_font()
{
default_font_id = new int(1);
}
}
Run Code Online (Sandbox Code Playgroud)
// lib/platform_abstraction.hpp …
Run Code Online (Sandbox Code Playgroud) 如果我运行这段代码:
#include <iostream>
#include <cstdint>
int main()
{
double a = -2.0;
const double b = -2.0;
using std::cout;
cout << "Direct cast double -> uint16:\n";
cout << "a1: " << static_cast<std::uint16_t>(a) << "\n";
cout << "b1: " << static_cast<std::uint16_t>(b) << "\n";
auto a2 = static_cast<std::uint16_t>(a);
auto b2 = static_cast<std::uint16_t>(b);
cout << "a2: " << a2 << "\n";
cout << "b2: " << b2 << "\n";
cout << "Indirect cast double -> uint16:\n";
cout << "a3: " << static_cast<std::uint16_t>(static_cast<std::int16_t>(a)) << …
Run Code Online (Sandbox Code Playgroud)