考虑一下这段代码:
struct Base
{
int x;
};
struct Bar : Base
{
int y;
};
struct Foo : Base
{
int z;
};
Bar* bar = new Bar;
Foo* foo = new Foo;
Base* returnBase()
{
Base* obj = !bar ? foo : bar;
return obj;
}
int main() {
returnBase();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这在Clang或GCC下不起作用,给我:
错误:不同指针类型'Foo*'和'Bar*'之间的条件表达式缺少一个强制转换Base*obj =!bar?foo:bar;
这意味着要编译我必须将代码更改为:
Base* obj = !bar ? static_cast<Base*>(foo) : bar;
Run Code Online (Sandbox Code Playgroud)
由于隐式转换为Base*存在,是什么阻止编译器这样做?
换句话说,为什么没有Base* obj = foo;演员而是使用?:操作员的工作呢?是因为我不清楚我想使用这Base部分吗?
c++ ternary-operator language-lawyer implicit-conversion c++17
我注意到大多数(如果不是所有)容器现在都需要它们的::iterator类型LegacySomethingIterator而不是SomethingIterator.
例如,std::vector<>::iterator 现在需要:
iteratorLegacyRandomAccessIterator
这似乎是大多数其它容器一样,都是需要自己迭代器从去SomethingIterator到LegacySomethingIterator.
还有"新"要求采用旧要求的名称,例如RandomAccessIterator,为什么这些要求被添加?在我看来,新的变种只会影响遗留的变种,没有差异.
为什么首先创建新的,他们的要求对我来说是一样的.为什么新的只是替换旧的要求而不是现在有两个不同的名称(例如RandomAccessIterator和LegacyRandomAccessIterator)?
我注意到大多数(如果不是全部)函数都会<algorithm>获得一个或多个额外的重载.所有这些额外的重载都会添加一个特定的新参数,例如,std::for_each来自:
template< class InputIt, class UnaryFunction >
UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f );
Run Code Online (Sandbox Code Playgroud)
至:
template< class ExecutionPolicy, class InputIt, class UnaryFunction2 >
void for_each( ExecutionPolicy&& policy, InputIt first, InputIt last, UnaryFunction2 f );
Run Code Online (Sandbox Code Playgroud)
这个额外ExecutionPolicy对这些功能有什么影响?
有什么区别:
std::execution::seqstd::execution::parstd::execution::par_unseq何时使用其中一个?
因此,显然C ++ 20正在得到std::to_address。
从cppreference页面上,它的用例对我来说似乎并不明确。我们已经有了operator&和std::addressof,为什么还需要另一个函数来为其参数提供地址?
我正在自学,编译器是如何工作的.我正在学习从小型64位Linux程序中读取GCC生成代码的反汇编.
我写了这个C程序:
#include <stdio.h>
int main()
{
for(int i=0;i<10;i++){
int k=0;
}
}
Run Code Online (Sandbox Code Playgroud)
使用objdump之后我得到:
00000000004004d6 <main>:
4004d6: 55 push rbp
4004d7: 48 89 e5 mov rbp,rsp
4004da: c7 45 f8 00 00 00 00 mov DWORD PTR [rbp-0x8],0x0
4004e1: eb 0b jmp 4004ee <main+0x18>
4004e3: c7 45 fc 00 00 00 00 mov DWORD PTR [rbp-0x4],0x0
4004ea: 83 45 f8 01 add DWORD PTR [rbp-0x8],0x1
4004ee: 83 7d f8 09 cmp DWORD PTR [rbp-0x8],0x9
4004f2: 7e …Run Code Online (Sandbox Code Playgroud) 我有一个哈希函数可以采用任何对象类型并哈希它,它在std::hash内部使用.因为std::hash不支持枚举类型,所以我创建了函数的重载,1用于枚举std::underlying_type,1用于其他类型:
template <typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
static std::size_t Hash(T const & t)
{
return std::hash<typename std::underlying_type<T>::type>()(t);
}
template <typename T, typename std::enable_if<!std::is_enum<T>::value>::type* = nullptr>
static std::size_t Hash(T const & t)
{
return std::hash<T>()(t);
}
Run Code Online (Sandbox Code Playgroud)
这工作正常.然后我尝试将它全部放入一个函数中std::conditional:
template <typename T>
static std::size_t Hash(T const & t)
{
typedef typename std::conditional<std::is_enum<T>::value, std::hash<typename std::underlying_type<T>::type>, std::hash<T>>::type Hasher;
return Hasher()(t);
}
Run Code Online (Sandbox Code Playgroud)
主要:
enum test
{
TEST = 2
};
int main() {
Hash<test>(TEST);
Hash<int>(5);
std::cin.get();
return …Run Code Online (Sandbox Code Playgroud) 下面的代码可以使用Visual Studio 2015成功编译,但使用Visual Studio 2017失败.Visual Studio 2017报告:
错误C2280:"std :: pair :: pair(const std :: pair&)":尝试引用已删除的函数
#include <unordered_map>
#include <memory>
struct Node
{
std::unordered_map<int, std::unique_ptr<int>> map_;
// Uncommenting the following two lines will pass Visual Studio 2017 compilation
//Node(Node&& o) = default;
//Node() = default;
};
int main()
{
std::vector<Node> vec;
Node node;
vec.push_back(std::move(node));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
看起来Visual Studio 2017显式需要移动构造函数声明.是什么原因?
考虑以下代码:
#define A -100
//later..
void Foo()
{
int bar = -A;
//etc..
}
Run Code Online (Sandbox Code Playgroud)
现在,这可以在我测试的一些主要编译器(MSVC,GCC,Clang)上很好地进行编译,并且bar == 100按预期进行,这是因为所有这些编译器的预处理器在标记之间插入了一个空格,因此您最终得到:
int bar = - -100;
Run Code Online (Sandbox Code Playgroud)
因为我希望代码尽可能地可移植,所以我去检查此行为是否由标准定义,但是我在此上找不到任何东西。这种行为是由标准保证的还是仅仅是编译器功能,是否还bar = --100;允许幼稚的方法(显然不会进行编译)?
随着CPU缓存变得越来越好,即使在测试a的优势时也会std::vector表现出色.出于这个原因,即使在我需要删除/插入容器中间的情况下,我通常会选择,但我意识到我从未测试过这个以确保假设是正确的.所以我设置了一些测试代码:std::liststd::liststd::vector
#include <iostream>
#include <chrono>
#include <list>
#include <vector>
#include <random>
void TraversedDeletion()
{
std::random_device dv;
std::mt19937 mt{ dv() };
std::uniform_int_distribution<> dis(0, 100000000);
std::vector<int> vec;
for (int i = 0; i < 100000; ++i)
{
vec.emplace_back(dis(mt));
}
std::list<int> lis;
for (int i = 0; i < 100000; ++i)
{
lis.emplace_back(dis(mt));
}
{
std::cout << "Traversed deletion...\n";
std::cout << "Starting vector measurement...\n";
auto now = std::chrono::system_clock::now();
auto index = vec.size() / 2;
auto itr = vec.begin() …Run Code Online (Sandbox Code Playgroud) 这是过载(4)在这里
在“异常”部分中,重载2、3、5、6(具有pos1和/或pos2参数)被命名为throwing std::out_of_range。
重载(4)没有“ pos”参数,但未标记noexcept。
是否抛出该结果取决于实现?
在GCC 7的libstdc ++中,它调用char_traits<char>::length和char_traits<char>::compare。这些似乎无法抛出,但没有标记noexcept。