今天我对这段代码片段的名称引用不明确这一事实感到震惊:
class A
{
private:
typedef int Type;
};
class B
{
public:
typedef int Type;
};
class D : A, B
{
Type value;//error: reference to 'Type' is ambiguous
};
Run Code Online (Sandbox Code Playgroud)
唔!假设您是 class 的作者,A
并且您的 class 已经被不同的人和不同的项目随处使用。有一天你决定重写你的A
类。这是否意味着您不能在不破坏他人代码的情况下在新类中使用任何新的(甚至私有的)名称?
这里的约定是什么?
这是一个语言律师问题。
\n首先,a.wait()
下面的代码是否总是返回?
std::atomic_int a{ 0 };\n\nvoid f()\n{\n a.store(1, std::memory_order_relaxed);\n a.notify_one();\n}\nint main()\n{\n std::thread thread(f);\n\n a.wait(0, std::memory_order_relaxed);//always return?\n\n thread.join();\n}\n
Run Code Online (Sandbox Code Playgroud)\n我相信标准的目的是a.wait()
总是得到回报。(否则atomic::wait/notify
就没用了,不是吗?)但我认为目前的标准文本不能保证这一点。
标准的相关部分位于 \xc2\xa731.6 [atomics.wait] 第 4 段:
\n\n\n对原子对象上的原子等待操作的调用
\nM
可以通过调用原子通知操作来解除阻塞M
,如果存在副作用X
,并且Y
满足M
以下条件:\n
\n- (4.1) \xe2\x80\x94 观察结果后,原子等待操作已阻塞
\nX
,- (4.2) \xe2\x80\x94在,的修改顺序
\nX
之前Y
M
- (4.3) \xe2\x80\x94
\nY
发生在调用原子通知操作之前。
和 \xc2\xa731.8.2 [atomics.types.operations] 第 29~33 段:
\n\n
void wait(T …
以下代码符合C++标准吗?
struct B
{
protected:
struct Type {};
};
struct D : B, B::Type
{};
int main()
{
D d;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在Compiler Explorer上试了一下.MSVC(VS 2017 RTW)接受它.gcc(7.3)和clang(6.0.0)拒绝它.
C++20std::atomic
有wait
和notify_*
成员函数,但没有wait_for
/ wait_until
。
std::atomic
使用Microsoft STL 实现WaitOnAddress
(当操作系统足够新时)。这个API有一个dwMilliseconds
参数,就像超时值一样。因此,从标准库编写者的角度来看,我认为缺少的功能很容易实现(至少在 Windows 8 或更高版本上)。我只是想知道为什么它不在 C++20 中。
但作为(便携式)用户代码编写者,我必须使用标准信号量和原子计数器来模拟行为。所以这是代码:
#include <concepts>
#include <atomic>
#include <type_traits>
#include <cstring>
#include <semaphore>
namespace detail
{
template <size_t N>
struct bytes
{
unsigned char space[N];
auto operator<=>(bytes const &) const = default;
};
//Compare by value representation, as requested by C++20.
//The implementation is a bit awkward.
//Hypothetically `std::atomic<T>::compare(T, T)` would be helpful. :)
template <std::integral T>
bool …
Run Code Online (Sandbox Code Playgroud) 在 C++20 (N4849) 中,关联容器extract()
和insert(node_handle)
/insert(hint, node_handle)
方法没有异常安全措辞。
但是对于merge()
,虽然有这样的措辞:
抛出:除非比较对象抛出,否则什么都没有。
位置:
22.2.6 关联容器 [associative.reqmts]
表 78:关联容器要求(除了容器)[tab:container.assoc.req]
第 799 页
显然,最初的提案 ( P0083R3 ) 旨在使其无投掷(第 5 页):
异常安全
如果容器的 Compare 函数是 no-throw(这是很常见的),那么移除、修改和插入节点都是 no-throw,除非修改值会抛出。如果修改值确实抛出,它会在所涉及的容器之外进行。
但为什么在该提案后面的拟议措辞中没有发言权?
在PEP 3103中,Guido正在讨论向Python添加一个switch/case语句以及各种思想,方法和对象.他在此发表了这样的声明:
另一个反对意见是,首次使用的规则允许这样的混淆代码:
Run Code Online (Sandbox Code Playgroud)def foo(x, y): switch x: case y: print 42
对于未经训练的人(不熟悉Python),这段代码就等同于:
Run Code Online (Sandbox Code Playgroud)def foo(x, y): if x == y: print 42
但这不是它的作用(除非它总是被调用与第二个参数相同的值).这已经通过建议不应该允许case表达式引用局部变量来解决,但这有点武断.
我不会认为自己没有训练或不熟悉Python,但没有任何东西跳出来,因为这两个代码块是不同的.
什么是他引用会使这两段代码执行不同?
考虑这段代码:
std::atomic<int> x{ 0 };
std::atomic<int> y{ 0 };
int a;
int b;
void thread1()
{
//atomic op A
x.store(1, std::memory_order_relaxed);
//fence X
std::atomic_thread_fence(std::memory_order_seq_cst);
//sequenced-before P, thus in SC order X=>P
//atomic op P
a = y.load(std::memory_order_seq_cst);//0
//reads-before(from-read) Q, thus in SC order P=>Q
}
void thread2()
{
//atomic op Q
y.store(1, std::memory_order_seq_cst);
//sequenced-before B, thus in SC order Q=>B
//atomic op B
b = x.load(std::memory_order_seq_cst);
}
int main()
{
std::thread t2(thread2);
std::thread t1(thread1);
t1.join();
t2.join();
assert(a == 1 || …
Run Code Online (Sandbox Code Playgroud) 我认为下面的C程序输出1:
#include <stdio.h>
int main()
{
unsigned int n=18u;
while ((n+17u)>=17u) n-=17u;
printf("%u\n",n+17u);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是在VC6,Visual Studio 2010或Visual Studio 2012中编译,都处于发布模式,程序不会输出任何内容而不会退出.
这是VS2012生成的汇编代码:
00BD1000 mov eax,12h
00BD1005 lea eax,[eax-11h]
00BD1008 jmp main+5h (0BD1005h)
Run Code Online (Sandbox Code Playgroud)
似乎编译器做了一些优化并生成了一个无限循环.
我认为((n + 17u)> = 17u)并不总是正确的,因为如果n == 0xFFFF..FF,n + 17u将换行到16u.
我错了,还是编译器错了?
我想编写一个M
接受不完整类型C
作为模板参数的类模板。但我也希望C
在最终定义时具有一些特征。
此代码是否有保证
template <auto> struct Dummy {};
template <typename C>
void check()
{
static_assert(std::is_trivial_v<C>);
}
template <typename C>
struct M : Dummy<&check<C>>
{
//static_assert(std::is_trivial_v<C>);//error: incomplete type
C * p;
};
struct Test;
M<Test> m;
int main()
{
return 0;
}
#if defined(FLAG)
struct Test {};
#else
struct Test { std::string non_trivial_member; };
#endif
Run Code Online (Sandbox Code Playgroud) c++ language-lawyer function-templates implicit-instantiation non-type-template-parameter
我在MSVC中编译了这些代码:
int a=sizeof(struct{char c;});
Run Code Online (Sandbox Code Playgroud)
和
int b=((struct{char c;} *)0,0);
Run Code Online (Sandbox Code Playgroud)
和
printf("%p",(struct{char c;} *)0);
Run Code Online (Sandbox Code Playgroud)
作为C代码,它们可以通过编译,但会出现警告(warning c4116: unnamed typeDefinition in Parentheses。如果给出名称,则为“ warning c4115: "Whatever" :named typeDefinition in Parentheses ");
作为 C++ 代码,它们在编译时会出现一堆错误。
我的问题是:
1.在C中,括号中的类型定义有效吗?为什么我会收到该警告?
2. 在C++中,括号中的类型定义有效吗?
编辑:
3.为什么?
c++ ×8
c++20 ×4
atomic ×2
c ×2
inheritance ×2
ambiguity ×1
base ×1
definition ×1
memory-model ×1
non-type-template-parameter ×1
parentheses ×1
private ×1
protected ×1
python ×1
semaphore ×1
splice ×1
stdatomic ×1
throws ×1
timeout ×1
unsigned ×1
visual-c++ ×1