小编sky*_*ack的帖子

polymorphic_allocator:何时以及为什么要使用它?

是关于cppreference的文档,是工作草案.

我必须承认,我不明白什么是真正的目的,polymorphic_allocator何时/为什么/如何使用它.
例如,pmr::vector具有以下签名:

namespace pmr {
    template <class T>
    using vector = std::vector<T, polymorphic_allocator<T>>;
}
Run Code Online (Sandbox Code Playgroud)

什么是polymorphic_allocator要约?std::pmr::vector对老式的提供有什么好处std::vector?我现在能做什么才能做到现在为止?
分配器的真正目的是什么?我应该何时使用它?

c++ allocator c++17

87
推荐指数
3
解决办法
1万
查看次数

为什么在C++ 20中不推荐使用std :: is_pod?

std::is_pod可能会在C++ 20中弃用.
这个选择的原因是什么?我应该用什么来代替std::is_pod知道某种类型是否真的是POD?

c++ type-traits

69
推荐指数
1
解决办法
6730
查看次数

sizeof(void())是一个合法的表达式吗?

[5.3.3/1]开始,我发现:

sizeof运算符不应用于具有函数或不完整类型的表达式

[3.9/5]我发现:

不完全定义的对象类型和cv void是不完整的类型

无论如何,因为sizeof不评估它的操作数,我会说这sizeof(void())是一个合法的表达式(实际上GCC编译它,结果是1).
另一方面,从这里开始,void在讨论sizeof时没有提及,既没有提到具有大小1的类型,也没有提到具有实现定义大小的类型的列表.

因此问题是:是sizeof(void())一种法律表达吗?
是否保证大小等于1?
或者这是一个导致UB的法律表达,这就是全部?

c++ sizeof void language-lawyer

50
推荐指数
4
解决办法
3754
查看次数

析构函数的使用=删除;

考虑以下课程:

struct S { ~S() = delete; };
Run Code Online (Sandbox Code Playgroud)

很快就问题的目的:我无法创建S类似的实例,S s{};因为我无法销毁它们.
正如评论中所提到的,我仍然可以创建一个实例S *s = new S;,但我也无法删除它.
因此,我可以看到删除析构函数的唯一用法是这样的:

struct S {
    ~S() = delete;
    static void f() { }
};

int main() {
    S::f();
}
Run Code Online (Sandbox Code Playgroud)

也就是说,定义一个只暴露一堆静态函数的类,并禁止任何创建该类实例的尝试.

删除的析构函数的其他用途(如果有的话)是什么?

c++ destructor c++11

46
推荐指数
5
解决办法
4805
查看次数

std :: function可以存储指向数据成员的指针吗?

cppreference,我发现:

类模板std :: function是一个通用的多态函数包装器.std :: function的实例可以存储,复制和调用任何Callable目标 - 函数,lambda表达式,绑定表达式或其他函数对象,以及指向成员函数和指向数据成员的指针.

我不明白为什么一个std::function应该能够存储这样的指针,我以前从未听说过这个功能.
它是否真的可能,我错过了某些内容或文档中的错误?

operator()在这种情况下应该怎么做?
文档中可以看出:

使用参数args调用存储的可调用函数目标.

无论如何,这里没有存储的可调用函数目标.我错了吗?

说实话,我甚至无法弄清楚这个函数的正确语法是什么,否则我会写一个例子来测试它.
如何使用以下模板来定义指向数据成员的指针?

template< class R, class... Args >
class function<R(Args...)>
Run Code Online (Sandbox Code Playgroud)

c++ stl data-members c++11 std-function

37
推荐指数
1
解决办法
1244
查看次数

无效{}是否合法?

这是这个问题的后续行动.
评价和在回答据说超过一次,更多的void{}没有一个有效的类型-ID,也不是一个有效的表达式.

这很好,它是有道理的,这就是全部.

然后我通过工作草案的[7.1.7.4.1/2](占位符类型扣除).
有人说:

[...]
- 对于使用return 包含占位符类型的返回类型声明的函数中发生的非丢弃  语句,  T 是声明的返回类型,并且  e 是return语句的操作数  .如果  return 语句没有操作数,那么  e 是  void{};
[...]

那么,void{}(概念上)合法与否?
如果它在工作草案中提到是可接受的(尽管只是作为- 如果它是一个 -陈述),它必须是合法的.这意味着它也decltype(void{})应该是有效的,作为一个例子.
否则,工作草案应该使用void()而不是void{}


嗯,说实话,我很确定我没有足够的技巧来指出工作草案中的错误,所以真正的问题是:我的推理出了什么问题?上面的子弹中提到了
什么void{},以及为什么在这种情况下它是一个法律表达?

c++ void language-lawyer return-type-deduction c++17

28
推荐指数
2
解决办法
673
查看次数

参数包必须位于参数列表的末尾...何时以及为何?

如果参数列表必须位于参数列表的末尾,如果后者绑定到类,则不会得到参数列表的原因,如果参数列表是成员方法声明的一部分,则放宽约束.

换句话说,这个编译:

class C {
    template<typename T, typename... Args, typename S>
    void fn() { }
};
Run Code Online (Sandbox Code Playgroud)

以下不是:

template<typename T, typename... Args, typename S>
class C { };
Run Code Online (Sandbox Code Playgroud)

为什么第一种情况是正确的,第二种情况不是?
我的意思是,如果它是合法的语法,那么在这两种情况下都不应该这样吗?

要清楚,真正的问题是我正在定义一个类似于下面的类:

template<typename T, typename... Args, typename Allocator>
class C { };
Run Code Online (Sandbox Code Playgroud)

将分配器类型作为最后一种类型将不胜感激,但我可以以某种方式解决它(无论如何,如果你有一个建议,它的赞赏,也许你的优雅比我的更优雅!).
那就是说,我收到了错误:

参数包'Args'必须位于模板参数列表的末尾

所以,我只是很好奇地完全理解为什么它在某些情况下被接受,但它不在其他一些情况下.

是一个类似的问题,但它只是解释了如何解决问题,这对我来说非常清楚.

c++ templates variadic-templates c++11

26
推荐指数
2
解决办法
3720
查看次数

如何从私有基类调用静态方法?

由于第三方库的布局,我有类似下面的代码:

struct Base
{
    static void SomeStaticMethod(){}
};

struct Derived1: private Base {};

struct Derived2: public Derived1 {
    void SomeInstanceMethod(){
        Base::SomeStaticMethod();
    }
};

int main() {
    Derived2 d2;
    d2.SomeInstanceMethod();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用MSVC获得编译器错误C2247:

Base :: SomeStaticMethod无法访问,因为Derived1使用private从Base继承.

我知道我不能访问Base从成员Derived2通过继承,因为私人符,但我仍然应该能够调用静态方法Base-无论之间的继承关系BaseDerived2.
如何解决歧义并告诉编译器我只是调用静态方法?

c++ static-methods private-inheritance

25
推荐指数
4
解决办法
2089
查看次数

decltype(void())中的void()究竟是什么意思?

这是对这个问题的跟进,更准确地说是这个答案的评论.

什么是void()decltype(void())代表什么呢?
它表示函数类型,表达式还是其他什么?

c++ void decltype language-lawyer c++11

24
推荐指数
2
解决办法
2255
查看次数

静态constexpr int vs老式枚举:何时以及为何?

这可能是一个基本问题,但我现在无法看到自己的反应.

请考虑以下代码:

template<bool b>
struct T {
    static constexpr int value = (b ? 42 : 0);
};

template<bool b>
struct U {
    enum { value = (b ? 42 : 0) };
};

int main() {
    static_assert(T<true>::value == 42, "!");
    static_assert(T<false>::value == 0, "!");
    static_assert(U<true>::value == 42, "!");
    static_assert(U<false>::value == 0, "!");
}
Run Code Online (Sandbox Code Playgroud)

我习惯使用类似的结构T,但我不止一次看过U用于相同目的的结构(主要是特征定义).

据我所知,它们都是在编译时解决的,它们解决了几乎相同的问题,但在我看来,它T比可读性更强U(我知道,我个人意见).

我的问题非常简单:有哪种技术原因可以解决哪一种解决方案比另一种更好?
更有甚者,其中一个不是一个可行的解决方案吗?

c++ enums constexpr c++11

23
推荐指数
3
解决办法
2989
查看次数