小编Kno*_*abe的帖子

在cppreference中atomic_compare_exchange_weak的示例代码是否正确?

http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange上,以下示例代码作为示例使用std::atomic_compare_exchange_weak:

void append(list* s, node* n)
{
    node* head;
    do {
        head = s->head;
        n->next = head;
    } while(! std::atomic_compare_exchange_weak(s->head, head, n));
}
Run Code Online (Sandbox Code Playgroud)

我的理解是,这已经比较的效果*(s->head)head,当我所相信的希望是比较s->headhead.std::atomic_compare_exchange_weak在这个例子中&(s->head),第一个参数应该是,还是我错过了什么?

更新:规格std::atomic_compare_exchange_weak说:

bool atomic_compare_exchange_weak(volatile A* object, C * expected, C desired) noexcept;
bool atomic_compare_exchange_weak(A* object, C * expected, C desired) noexcept;
Run Code Online (Sandbox Code Playgroud)

效果:原子地,比较对象指向的内存的内容...与预期中的内容相等...

我认为这意味着*object与之相比较expected,但进一步的研究表明,实际意义是*object与之比较*expected(即,"在expected"中的意思是"指向expected").这意味着我原来问题的答案是"不,没有必要s->head在cppreference中获取示例代码中的地址".但object …

c++ c++11

8
推荐指数
1
解决办法
2013
查看次数

成员函数模板专业化可能具有与主模板不同的访问级别吗?

关于删除函数的问题的答案提到了成员函数模板如何不能在类范围内专门化.这让我想知道成员函数模板专业化是否可能具有与主模板不同的访问级别.在下面的代码中,我正在尝试使用公共成员函数模板的私有特化:

#include <iostream>

class Foo {
public:
  template<typename T>
  void func(T) { std::cout << "Public\n"; }

private:
  template<>
  void func<char>(char) { std::cout << "Private\n"; }

  friend int main();
};

int main()
{
  Foo f;
  f.func(10);
  f.func('a');
}
Run Code Online (Sandbox Code Playgroud)

使用最新的MSVC,它可以编译,运行并生成预期的输出:

Public
Private
Run Code Online (Sandbox Code Playgroud)

使用g ++ 4.8和Clang 3.2,代码被拒绝.Clang说:

error: explicit specialization of 'func' in class scope
void func<char>(char) { std::cout << "Private\n"; }
     ^
Run Code Online (Sandbox Code Playgroud)

据推测,g ++和Clang使用14.7.3/2的C++ 11作为他们行为的基础,但我认为可能会有一点摆动空间,因为3.3.6/3表示全局范围是命名空间,并且全局命名空间(间接)包含模板特化.

我的问题不是关于标准的这些部分或关于这些编译器的任何行为,而是关于成员函数模板是否可能具有与通用模板具有不同访问级别的特化.例如,是否可以拥有公共成员函数模板和该模板的私有特化?

c++ templates c++11

8
推荐指数
1
解决办法
513
查看次数

为什么不运行*为unique_ptr noexcept?

在C++ 11和草案C++ 14中,取消引用运算符(operator*operator->)shared_ptr都是noexcept.但是unique_ptr,operator->noexcept,但是operator*,不是.为什么不operator*unique_ptr noexcept(或者,为什么operator*shared_ptr noexcept)?

c++ smart-pointers noexcept c++11 c++14

7
推荐指数
0
解决办法
125
查看次数

为什么不能使用[[deprecated]]弃用模板?

C++ 14允许将[[deprecated]]属性应用于(根据7.6.5/2)"类的声明,typedef-name,变量,非静态数据成员,函数,枚举或模板专业化." 值得注意的是缺少模板.所以给出一个模板:

template<class T>
class MyOldRefCountingPointer {
    ...
};
Run Code Online (Sandbox Code Playgroud)

我可以弃用,比方说MyOldRefCountingPointer<void>,

template<>
class
[[deprecated ("Use std::shared_ptr<void> instead of MyOldRefCountingPointer")]]
MyOldRefCountingPointer<void> {
    ...
};
Run Code Online (Sandbox Code Playgroud)

但我不能弃用一般模板:

template<class T>
class
[[deprecated ("Use std::shared_ptr instead of MyOldRefCountingPointer")]]
MyOldRefCountingPointer {
    ...
};
Run Code Online (Sandbox Code Playgroud)

是什么原因导致不允许弃用模板?

更新

如何在不产生警告的情况下使用已弃用的模板的示例如下:

template<class T>
class
[[deprecated]]
OldClass {};

template<template<class> class C = OldClass>   // use deprecated template as
void f()                                       // default template parameter
{
}
Run Code Online (Sandbox Code Playgroud)

g ++和Clang都没有在这里发出警告.Coliru的例子.

c++ templates deprecated c++14

7
推荐指数
2
解决办法
514
查看次数

如何启用clang-tidy的"现代化"检查?

我刚刚安装了ClangOnWin,我正试图让clang-tidy"现代化"检查工作.不幸的是,clang-tidy似乎并不了解它们:clang-tidy -list-checks foo.cpp -- | grep modernize没有输出.

这里列出 "现代化"检查,但该页面似乎记录了Clang 3.8,我安装的版本是3.7.但是,3.7版是LLVM下载页面中列出的当前版本.

clang-tidy知道各种安全检查,所以我认为我已正确安装.例如,clang-tidy -list-checks foo.cpp -- | grep security产生这个:

clang-analyzer-security.FloatLoopCounter
clang-analyzer-security.insecureAPI.UncheckedReturn
clang-analyzer-security.insecureAPI.getpw
clang-analyzer-security.insecureAPI.gets
clang-analyzer-security.insecureAPI.mkstemp
clang-analyzer-security.insecureAPI.mktemp
clang-analyzer-security.insecureAPI.rand
clang-analyzer-security.insecureAPI.strcpy
clang-analyzer-security.insecureAPI.vfork
Run Code Online (Sandbox Code Playgroud)

是否有一些特殊的东西我需要做以启用检查,如modernize-use-overridemodernize-use-nullptr

clang clang-static-analyzer clang++ clang-tidy

7
推荐指数
2
解决办法
4187
查看次数

为什么向量被认为是nothrow_move_constructible?

向量移动构造函数的规范是(复制出标准):

vector(vector&&);
Run Code Online (Sandbox Code Playgroud)

注意缺乏noexcept.但是gcc 4.8和Clang 3.2报告都std::is_nothrow_move_constructible<std::vector<int>>::value返回true(即1):

#include<vector>
#include<iostream>

int main()
{
  std::cout << std::is_nothrow_move_constructible<std::vector<int>>::value << '\n';
}
Run Code Online (Sandbox Code Playgroud)

造成这种明显差异的原因是什么?

c++ c++11

6
推荐指数
1
解决办法
460
查看次数

如何在派生类中使用shared_from_this而不需要多余的RC操作?

如果我想shared_ptr<Derived>在继承自基类的层次结构中创建派生类成员函数,我可以使用shared_from_thisstatic_pointer_cast:

class Base: public std::enable_shared_from_this<Base> {
};

class Der: public Base {
public:
  std::shared_ptr<Der> make_SP_to_Me () 
  { return std::static_pointer_cast<Der>(shared_from_this()); }
};
Run Code Online (Sandbox Code Playgroud)

我关心的是static_pointer_cast通过lvalue-ref-to-const接受它的参数,所以当shared_ptr<Der>创建new时,控制块中的引用计数会递增.当shared_ptr<Base>返回的from shared_from_this被销毁时,控制块中的refcount将再次递减.我很惊讶地看到没有static_pointer_cast超载采用rvalue来避免操纵控制块中的refcount.

shared_ptr<T>有一个模板化的构造函数采用shared_ptr<U>执行移动的类型的rvalues ,从而避免了进行refcount 操作的需要.有什么理由static_pointer_cast不做同样的事情吗?是否有一些方法让我编写上面的代码,不涉及不必要的refcount操作?

c++ shared-ptr c++11

6
推荐指数
1
解决办法
226
查看次数

禁用对异常的支持是否也会禁用对“std::move_if_noexcept”的支持?

一些商店(例如,一些视频游戏开发团队)在其构建环境中禁用对异常的支持。禁用异常后,开发人员将没有理由声明他们的移动操作noexcept(假设此类代码甚至可以编译)。但是标准库实现应该std::move_if_noexcept在实现某些操作时调用(例如,std::vector::push_back)。标准库实现通常会在编译期间检查异常是否被禁用,如果是,则使用std::move而不是std::move_if_noexceptstd::is_nothrow_move_constructible当禁用异常时,编译器是否会导致所有类型返回 true?std:move_if_noexcept或者禁用对异常的支持是否会产生无法启用移动操作的意外副作用?

我对实践中发生的事情感兴趣。我知道禁用异常支持会让我们脱离 C++ 标准的范围。

c++ exception move-semantics c++11

5
推荐指数
1
解决办法
455
查看次数

当 T 是引用类型时,为什么 const T&amp; 参数中的 const 会消失?

以下代码显示,如果const使用引用类型(例如,int&)实例化采用ref-to-参数的模板,则该参数不是const

#include <iostream>

template<typename T>
void f(const T& arg)         // arg isn't const if T is a reference type
{
  arg = -1;
}

int main()
{
  int x = 0;
  f<int&>(x);                // instantiate f with reference type
  std::cout << x << '\n';    // prints -1 under gcc, clang, and msvc
}
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?

我的猜测是,最初的类型argisint & const &并且它以某种方式转换为int&. 如果是这样,就标准而言,这究竟是如何发生的?如果这不是正在发生的事情,那是什么?

c++ templates type-deduction

5
推荐指数
1
解决办法
556
查看次数

通过强制转换为 int 来访问原始内存是否违反严格别名?

假设我想为 an 动态分配空间int并将最大可表示值写入该内存。我想到了这段代码:

auto rawMem = std::malloc(sizeof(int));         // rawMem's type is void*
*(reinterpret_cast<int*>(rawMem)) = INT_MAX;    // INT_MAX from <limits.h>
Run Code Online (Sandbox Code Playgroud)

这段代码是否违反了 C++ 关于严格别名的规则?g++ 和 clang++ 都不会抱怨-Wall -pedantic.

如果代码不违反严格别名,为什么不呢?std::malloc返回void*,因此虽然我不知道返回的内存的静态和动态类型是什么std::malloc,但没有理由认为其中任何一个都是intchar而且我们不会以or 的方式访问内存unsigned char

我想认为代码是干净的,但如果是的话,我想知道为什么。

只要我在附近,我也想知道内存分配函数(std::mallocstd::operator new)返回的内存的静态和动态类型。

c++ memory strict-aliasing

5
推荐指数
1
解决办法
328
查看次数