#include <set>
#include <string>
#include <cassert>
using namespace std::literals;
int main()
{
auto coll = std::set{ "hello"s };
auto s = "hello"s;
coll.insert(std::move(s));
assert("hello"s == s); // Always OK?
}
Run Code Online (Sandbox Code Playgroud)
C ++标准是否保证插入关联容器失败不会修改rvalue-reference参数?
c++ stl rvalue-reference language-lawyer pass-by-rvalue-reference
我想在编译期间检查类型是否是特定模板的实例化.
例如:
std::vector<int> 实例化 std::vectorstd::array<int, 5> 实例化 std::array我可以进行适用于案例1的测试,但不适用于案例2.
#include <iostream>
#include <type_traits>
#include <string>
#include <vector>
#include <array>
#include <queue>
template<template<typename...> class, typename...>
struct is_instantiation : public std::false_type {};
template<template<typename...> class U, typename... T>
struct is_instantiation<U, U<T...>> : public std::true_type {};
int main() {
using A = std::vector<int>;
std::cout << is_instantiation<std::vector, A>::value << "\n";
std::cout << is_instantiation<std::queue, A>::value << "\n";
// std::cout << is_instantiation<std::array, A>::value << "\n";
}
Run Code Online (Sandbox Code Playgroud)
如何让它适用于这两种情况?
我试过汽车,但无法使它工作.
我搜索了这个问题的答案,却找不到答案.请考虑以下代码:
struct Foo
{
int *bar;
Foo(int barValue) : bar(new int(barValue)) {}
~Foo() { do_this(); }
void do_this() { delete bar; bar = nullptr; }
};
int main()
{
const Foo foo(7);
}
Run Code Online (Sandbox Code Playgroud)
do_this()不能在一个const对象上调用,所以我做不了类似的事情foo.do_this().在某些情况下do_this(),在析构函数之外调用也是有意义的,这就是为什么我不想简单地在析构函数定义中包含代码.因为do_this()修改成员变量,我不能将其声明为const.
我的问题是:将析构函数可以调用do_this()一个在const当对象被销毁的对象?
我尝试了它并没有收到任何错误,但我想确保一旦我的程序终止,我不会导致内存泄漏.
下面的代码片段由gcc,icc和msvc(最新的问题)精确编译,但是<source>:6:9: error: calling a private constructor of class 'B<int>'在标记的行中叮当作响.然而它适用于免费模板功能,如代码所示:
struct A {
template<class T>
static void create () {
T();
}
};
template<class T>
void create() {
T();
}
template<typename T>
struct B {
friend void A::create<B>();
friend void create<B>();
private:
B() = default;
};
int main() {
A::create<B<int>>(); // clang trips here
create<B<int>>(); // fine!
}
Run Code Online (Sandbox Code Playgroud)
在此上下文中,非模板类的静态模板成员与自由模板函数之间可能有什么区别?
(这个问题的灵感来自于如何生成编译错误以防止某些VALUE(非类型)进入函数?)
比方说,我们有一个单一的参数foo,语义定义为
int foo(int arg) {
int* parg;
if (arg != 5) {
parg = &arg;
}
return *parg;
}
Run Code Online (Sandbox Code Playgroud)
上面的整个代码用于说明一个简单的想法 - 函数返回它自己的参数,除非参数等于5,在这种情况下行为是未定义的.
现在,挑战 - 以这种方式修改函数,如果它的参数在编译时已知,则应生成编译器诊断(警告或错误),如果不是,则在运行时仍未定义行为.解决方案可能依赖于编译器,只要它可以在四大编译器中的任何一个中使用.
以下是一些无法解决问题的潜在路线:
constexpr- 这不能解决问题,因为即使编译器看到未定义的行为,它们也不会在我的测试中产生诊断 - 相反,gcc会插入ud2指令,这不是我想要的.为什么通过void*未定义的行为而不是编译错误来删除对象?
void foo(void* p) {
delete p;
}
Run Code Online (Sandbox Code Playgroud)
这段代码编译并生成代码,虽然gcc和clang上有警告(令人惊讶的是,ICC没有发出警告):
:2:5:警告:无法删除带有指针''''''的类型'void*'[-Wdelete-incomplete]
为什么不是简单的格式错误的程序,语法无效?貌似标准没有花太多时间就可以了,在说[expr.delete]这
这意味着无法使用void*类型的指针删除对象,因为void不是对象类型.
我有什么理由不知道为什么这不会触发硬编译错误?
c++ void-pointers undefined-behavior language-lawyer delete-operator
我有一段C++代码,我不确定它是否正确.请考虑以下代码.
#include <memory>
#include <vector>
#include <map>
using namespace std;
int main(int argc, char* argv[])
{
vector<map<int, unique_ptr<int>>> v;
v.resize(5);
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
GCC编译这段代码没有问题.但是,英特尔编译器(版本19)因错误而停止:
/usr/local/ [...] /include/c++/7.3.0/ext/new_allocator.h(136): error: function "std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2> &) [with _T1=const int, _T2=std::unique_ptr<int, std::default_delete<int>>]" (declared at line 292 of "/usr/local/ [...] /include/c++/7.3.0/bits/stl_pair.h") cannot be referenced -- it is a deleted function
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^
detected during:
[...]
instantiation of "void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type={std::size_t={unsigned long}}) [with _Tp=std::map<int, std::unique_ptr<int, std::default_delete<int>>, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int, …Run Code Online (Sandbox Code Playgroud) 无论我到哪里,我都会看到以下代码:
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = ip;
Run Code Online (Sandbox Code Playgroud)
在C++中,同样的想法通常表示为
sockaddr_in addr = {}; // unneccesary(?) value-initialzation
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = ip;
Run Code Online (Sandbox Code Playgroud)
然而,在我设置这些成员之前,我没有看到(在官方文档方面)我有任何要求将结构清零!是的,通常BSD套接字实现做有一个sin_zero用于定义的成员sockaddr_in,但他们总是说需要进行填充成员,对齐的大小sockaddr_in用sockaddr.他们从不要求人们将任何具体内容放入其中.
有没有真正的,文件证明需要零出结构?
PS之前VTC问题的若干SO一个问题的有关副本memset上sockaddr_in,请确保该问题您所提出的建议为重复有正式文件,而不是"以防万一未使用成员的初始化"只是猜测的任何链接.
std::map::emplace在标准中以某种方式创建对象(即调用构造函数)的点是什么?如果是,是否在检查此类密钥存在之前或之后发生?
在以下情况下,这很重要:
struct X {};
std::map<int, std::unique_ptr<X> > map;
void f(int x) {
map.emplace(x, new X);
}
Run Code Online (Sandbox Code Playgroud)
如果首先创建对象,则一切都很酷(构造unique_ptr并拥有资源),但如果在检查后构造它,则在重复键的情况下存在内存泄漏.
所有我能在标准中找到的是
插入一个value_type对象t,使用
std::forward<Args>(args)...if和仅当容器中没有元素且使用等效于t的键的元素构造 .
这没有解决我的问题.
假设我最简单std::set:
std::set<std::string> my_set;
Run Code Online (Sandbox Code Playgroud)
现在,我有一个函数可以接受const char*并需要告诉我该字符串是否存在,以最直接的方式实现:
bool exists(const char* str) {
return my_set.count(str) > 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,这显然是效率损失。在这里无缘无故地发生(潜在的)动态内存分配,然后再进行释放。
我们该如何消除呢?我想与用作std::string键类型进行比较char*。一种方法是在unique_ptr<char>自定义比较器中使用而不是我的键类型,但是那样会很尴尬。
实际上,该问题可以推广到更广泛的情况,即“如何在不转换为键类型的情况下调用提供的类型的比较?”
PS我已经看过std :: string作为map键和map.find()的效率,但是我对答案不满意,这有效地重申了不需要这种优化,尽管这显然是错误的。