小编Bro*_*her的帖子

传递指向在某个基类中私有继承的类型的指针

我始终认为私有继承仅仅意味着类型不会告诉外部它是从某个基类继承的。不过,似乎还有更多的限制。

考虑以下最小示例:

struct MyInterface {};

struct MyImpl : private MyInterface {};

struct Inherited : public MyImpl {
    // Error: 'MyInterface' not accessible because 'MyImpl' uses 'private' to inherit from 'MyInterface'
    void doSomething(MyInterface* mi) {}
};

struct Noninherited {
    // All fine!
    void doSomething(MyInterface* mi) {}
};
Run Code Online (Sandbox Code Playgroud)

Clang、GCC 和 MSVC 都拒绝此代码。鉴于我之前的假设,我本以为一切都会好起来的。

doSomething只是需要一个指向 的指针MyInterface,但它不会告诉外界其继承层次结构中Inherited有哪些MyInterface内容。在我看来,私有继承不仅不告诉外界继承结构,反而使整个继承结构完全“忘记”继承类型的存在。

这是理解私有继承的正确“思维模型”吗?还有其他意想不到的限制吗?

c++ inheritance private-inheritance

31
推荐指数
1
解决办法
1464
查看次数

是否有必要在 std::coroutine_handle 上调用 destroy ?

std::coroutine_handle是C ++ 20的新协程的一个重要部分。例如,发电机经常(总是?)使用它。在我见过的所有示例中,在协程的析构函数中手动销毁句柄:

struct Generator {
    // Other stuff...
    std::coroutine_handle<promise_type> ch;

    ~Generator() {
        if (ch) ch.destroy();
    }
}
Run Code Online (Sandbox Code Playgroud)

这真的有必要吗?如果是的话,为什么没有这个已经被完成的coroutine_handle,是有一个RAII版本coroutine_handle,其行为这种方式,并会如果我们忽略了发生什么destroy电话?

例子:

  1. https://en.cppreference.com/w/cpp/coroutine/coroutine_handle(感谢 463035818_is_not_a_number
  2. C++20 标准也在 9.5.4.10 Example 2(在 N4892 上检查)中提到它。
  3. (德语)https://www.heise.de/developer/artikel/Ein-unendlicher-Datenstrom-dank-Coroutinen-in-C-20-5991142.html
  4. https://www.scs.stanford.edu/~dm/blog/c++-coroutines.html - 提到如果不调用它会泄漏,但没有引用标准中的段落或为什么不引用在 的析构函数中调用std::coroutine_handle

c++ coroutine c++20

12
推荐指数
1
解决办法
269
查看次数

C++23 标准中的 bfloat16_t 是什么?

Cppreference文档包含 5个stdfloat新类型:float16_tfloat32_tfloat64_tfloat128_tbfloat16_t虽然前 4 种类型是不言自明的(分别是 16、32、64 和 128 位的浮点数),但最后一种类型bfloat16_t对我来说根本不清楚。这个类型代表什么?它的名字中的是什么b意思?

c++ floating-point c++23

9
推荐指数
1
解决办法
2055
查看次数

C++ 17标准是否保证联合的地址与其成员的地址相同?

我目前正致力于编写池分配器.我的问题归结为以下代码:

template <typename T>
union myUnion {
    T data;
    myUnion<T>* nextUnion;
};

void someFunction(){
    myUnion<T> mu;
    T* t = new (std::addressof(mu.data)) T();
    //some code
    myUnion<T>* mu2 = reinterpret_cast<myUnion<T>*>(t);
}
Run Code Online (Sandbox Code Playgroud)

mu的地址是否与mu2相同?

c++ allocator

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

鉴于 C++23 对 constexpr 的放宽,constexpr 不能成为默认值吗?

关键字constexpr在引入 C++11 标准时对其函数实施了相当严格的限制。C++14 和 C++20 放宽了这些限制(最值得注意):

  • C++14 允许多个return语句static_assert等。
  • C++20 允许try并且asm

C++23 进一步软化了这些限制。从我在cppreference中看到的,constexprfor函数似乎只剩下以下含义:

  • 它不能是协程
  • 对于构造函数和析构函数,该类必须没有虚拟基类
  • 对于 constexpr 函数模板和类模板的 constexpr 成员函数,至少一种特化必须满足上述要求。

C++23 甚至删除了 constexpr 函数必须在编译时对于p2448r2中的任何类型“可计算”的限制。根据我的理解,这完全消除了constexpr在编译时评估函数的想法。

是这样吗?如果是这样,constexpr函数还有什么用处呢?

c++ language-design constexpr constexpr-function c++23

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

返回在函数内填充的 const char* 向量是否是明确定义的行为

我目前正在学习 vulkan。在其中一个教程中,我看到了一个大致执行以下操作的函数:

#define SOMESTRING "Hello World!"

std::vector<const char*> buildVector() {
    std::vector<const char*> vec;
    vec.push_back(SOMESTRING);
    return vec;
}
Run Code Online (Sandbox Code Playgroud)

当我看到这个时,我想知道:这是定义的行为吗?字符串的内容不是"Hello World!"位于堆栈上,因此一旦函数返回就无效吗?如果这是未定义的行为,那么正确的方法是什么?不幸的是,std::string由于 vulkan API ,使用不是一种选择。

c++ c-strings stdvector

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

Visual Studio 2017是否完全支持具有[[deprecated]]属性的N4266?

我正在研究C++ 17的新功能.我偶然发现了N4266这个功能,它说现在枚举和名称空间也可以使用属性.不同消息来源称,Visual Studio 2017已经完全支持此功能.我用[[deprecated]]属性编写了一个测试.对于名称空间,这非常有效.但是,没有为枚举生成警告.我的实施中有错误吗?我错过了什么?

enum MyEnum
{
    val = 0,
    vaal[[deprecated]] = val
};

void test()
{
    MyEnum e  = MyEnum::vaal; //Should emit Warning, but does not
    MyEnum e2 = MyEnum::val;  //No Warning
}
Run Code Online (Sandbox Code Playgroud)

我正在使用Visual Studio Community 2017版本15.3.5.说明自VS2015以来它应该得到支持./ std:使用c ++ 17.

也说明这应该是正确的语法.

如果我使用枚举或枚举类没有区别.

c++ visual-studio c++17

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

是否可以将动态分配的数组传递给需要数组引用的函数?

预先说明:我知道在这里做我所要求的不是一个好主意。这只是来自病态语言好奇心的问题,而不是实际使用中的问题。我在这里应用的规则完全是任意的。

假设我们有一个完全定义如下的函数。它不得更改为除此之外的任何内容,不允许模板或函数重载。这个函数的实现也不能改变(并且可以被视为未知)。然而,我们知道该参数用作输出参数。

void my_func(int (&arr)[10]);
Run Code Online (Sandbox Code Playgroud)

在另一个函数中,我们动态分配一个数组。这个分配也不能改变,我们不允许在栈上分配。也不允许进一步分配。

int* my_arr = new int[10];
Run Code Online (Sandbox Code Playgroud)

是否有可能以某种方式调用my_func并传递它my_arr?换句话说,是否有可能以某种方式欺骗类型系统将其my_arr视为数组而不是指针?

朴素的铸造不能解决问题,所有这些都会导致编译错误:

my_func((int[10])my_arr);
my_func(static_cast<int[10]>(my_arr));
my_func(reinterpret_cast<int[10]>(my_arr));
Run Code Online (Sandbox Code Playgroud)

另一个注意事项:我想欺骗类型系统。我不想从堆栈数组等复制数据。为什么?再次:病态的好奇心。

c++ arrays pass-by-reference

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

内在向量元素类型(如 epi64x 或 pi32)的名称和含义是什么?

英特尔内在函数的名称中内置了向量的子类型。例如,_mm_set1_ps是 a ps,即packed single-precisionaka。A float。尽管它们中的大多数的含义是明确的,但它们的“全名”packed single-precision从功能描述中并不总是清晰的。我创建了下表。不幸的是,有些条目丢失了。它们有何价值?其他问题见表下方。

缩写 全名 C/++ 等效项
附注 压缩单精度 漂浮
酸碱度 压缩半精度 没有任何**
PD 压缩双精度 双倍的
个人电脑 压缩半精度复数 没有任何**
pi8 ??? int8_t
PI16 ??? int16_t
pi32 ??? int32_t
Epi8 ??? int8_t
表观16 ??? int16_t
表观32 ??? int32_t
表观64 ??? int64_t
外延64x ??? int64_t

附加问题:

  1. 我有错过任何吗?
  2. epiX和 和有什么区别piX
  3. 为什么不pi64存在?
  4. epi64和 和有什么区别epi64x

** 我发现了这个,但似乎没有标准方法来表示 C/++ 中的半精度(复数)值。如果这有任何改变,请纠正我。

sse intel intrinsics sse2 mmx

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

何时关闭光栅化步骤是否有意义?

在vulkan中,有一个结构是管道创建所需的,命名为VkPipelineRasterizationStateCreateInfo.在这个结构中有一个名为的成员rasterizerDiscardEnable.如果将此成员设置为,VK_TRUE那么在光栅化步骤之前将丢弃所有基元.这会禁用帧缓冲区的任何输出.

我想不出这可能有意义的场景.在哪些情况下它可能有用吗?

c++ vulkan

3
推荐指数
2
解决办法
536
查看次数