假设我有两个structs:
struct X {};
struct Y { X x; }
Run Code Online (Sandbox Code Playgroud)
我有功能:
void f(X&);
void f(X&&);
Run Code Online (Sandbox Code Playgroud)
我怎样写一个函数g()是需要Y&或Y&&只有完美的转发X&或X&&至f(),分别为:
template <typename T>
void g(T&& t) {
if (is_lvalue_reference<T>::value) {
f(t.x);
} else {
f(move(t.x));
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码说明了我的意图,但随着参数数量的增加,它的可扩展性不高.有没有办法让它完美转发并使其可扩展?
根据C ++ 17 [basic.compound] / 3:
指针类型的每个值都是以下之一:
- 指向对象或函数的指针(据说该指针指向对象或函数),或
- 一个超出对象末尾的指针(8.7),或者
- 该类型的空指针值(7.11),或者
- 无效的指针值。
该malloc函数返回一个指针值。让我们假设调用成功,因此返回值不为null。malloc([c.malloc])的规范没有声明它在返回的存储中创建了任何对象,因此似乎“无效的指针值”是最没有意义的类别。
如果被调用的函数pthread_create具有以下结构
try{
...code....
pthread_detach(pthread_self());
pthread_exit(NULL);
}catch(...){
std::cout<<"I am here"<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
为什么省略号的异常处理程序在执行时被调用pthread_exit?(请注意std::exception,例如,不会抛出)
我有一个关于GCC-Wiki文章的问题.在标题"总结"下,给出了以下代码示例:
线程1:
y.store (20);
x.store (10);
Run Code Online (Sandbox Code Playgroud)
线程2:
if (x.load() == 10) {
assert (y.load() == 20)
y.store (10)
}
Run Code Online (Sandbox Code Playgroud)
据说,如果释放所有商店并获得所有负载,则线程2中的断言不会失败.这对我来说很清楚(因为线程1中x的存储与线程2中x的加载同步).
但现在出现了我不理解的部分.还有人说,如果所有商店都被释放并且消耗了所有负载,那么结果是相同的.来自y的负载是否可能在x的负载之前被提升(因为这些变量之间没有依赖关系)?这意味着线程2中的断言实际上可能会失败.
我们知道,下面的代码格式错误,因为该成员x位于依赖基类中.但是,更改x为this->x指示的行将修复错误.
template <typename T>
struct B {
int x;
};
template <typename T>
struct C : B<T> {
void f() {
int y = x; // Error!
}
};
int main() {
C<int> c;
c.f();
}
Run Code Online (Sandbox Code Playgroud)
我想解释一下标准中如何指定这种行为.根据[temp.dep]/3:
在类或类模板的定义中,如果基类依赖于模板参数,则在类模板或成员的定义点或在实例化实例化期间,不会在非限定名称查找期间检查基类作用域.类模板或成员.
这似乎解释了为什么x单独使用失败.x在定义点查找名称,不检查基类范围.但是,如果我们使用this->x怎么办?现在名称x是依赖的,其查找被推迟到实例化.但引用的段落似乎暗示即使在实例化时x也不应该找到,因为查找xin 仍然this->x是不合格的查找.
显然,实现不会以这种方式运行,并且人们普遍认为,一旦模板被实例化,就会搜索基类范围.
请考虑以下示例代码:
class C
{
public:
int* x;
};
void f()
{
C* c = static_cast<C*>(malloc(sizeof(C)));
c->x = nullptr; // <-- here
}
Run Code Online (Sandbox Code Playgroud)
如果由于任何原因我不得不忍受未初始化的内存(当然,如果可能的话,我会打电话new C()),我仍然可以调用放置构造函数.但是,如果我省略这一点,如上所述,并手动初始化每个成员变量,是否会导致未定义的行为?即绕过构造函数本身未定义的行为,或者用类外的一些等效代码替换调用它是否合法?
(通过另一个完全不同的问题遇到这个问题;要求好奇......)
我正在玩一些使用shared_ptr和enable_shared_from_this,而我遇到了一些我不太懂的东西.
在我的第一次尝试中,我构建了这样的东西:
class shared_test : std::enable_shared_from_this<shared_test> {
public:
void print(bool recursive) {
if (recursive) {
shared_from_this()->print(false);
}
std::cout << "printing" << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
请注意,此类私有地扩展std :: enable_shared_from_this.这显然有很大的不同,因为执行这样的事情:
int main() {
auto t(std::make_shared<shared_test>());
t->print(true);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
抛出bad_weak_ptr异常.好像我从std :: enable_shared_from_this中将类定义更改为公开的,这就是find.
为什么,我在这里想念什么?并没有办法使它适用于私有继承,因为shared_test类的"外部世界"不需要知道它是否允许共享...(至少,如果你问我,还是我又想念一些东西?)
c++ shared-ptr private-inheritance c++11 enable-shared-from-this
C++标准提案的代码中的"N"和"P"是什么意思?
以下是GCC标准支持状态列表.您可以看到提案类似于"P0245R1"或"N4051"等.(我认为"R"表示"修订").
c++ ×10
c++11 ×2
templates ×2
atomic ×1
c ×1
c++17 ×1
cancellation ×1
declaration ×1
exception ×1
expression ×1
grammar ×1
iso ×1
malloc ×1
memory-model ×1
name-lookup ×1
pointers ×1
pthreads ×1
shared-ptr ×1
stdatomic ×1
syntax ×1