小编x43*_*2ph的帖子

为什么std :: is_aggregate <T>是一个聚合?

我总是给人这样的印象,像std::is_samestd::is_voidstd::is_aggregate应该继承于std::integral_constant或更确切的说是std::bool_constant

但是,聚集类在定义上一定不能具有基类,但是当我像T在中那样使用这些类型时std::is_aggregate_v<T>,我会得到true。所以很显然,它们不是std::bool_constant

所以我的问题是:

std::is_aggregate_v<std::is_aggregate<void>>至少对于GCC和Clang,为什么如此?标准是否没有指定std::is_aggregate衍生自std::bool_constant?如果不是,这是否意味着将上述行的值留作实现细节?

c++ std type-traits c++17

11
推荐指数
1
解决办法
581
查看次数

如何使非成员get &lt;N&gt;用于命名空间中的自定义类[C ++ 17]

C ++ 17引入了结构化绑定声明:auto [a, b] = some_tuple;

这对于像std :: tuple这样的东西都是开箱即用的。也可以使其适用于自定义类型,您只需(除其他外)提供一个get-function模板即可,作为成员或在自定义类之外。

对于标准类,这是通过非成员get放置在std-namespace中来完成的:auto a = std::get<0>(some_tuple);works,但不是auto a = some_tuple.get<0>();

但这对我来说很奇怪:由于我们必须为get显式指定模板参数N,因此ADL不起作用,例如,我们不能只写auto a = get<0>(some_tuple);。但是,使用元组的结构化绑定声明也不应工作,因为它只是诸如get<N>(some_tuple)or或some_tuple.get<N>()(modulo some &)之类的调用的语法糖!确实,当我在命名空间内仅为我的自定义类提供get的非成员版本时,它将无法正常工作! 编辑:自定义类的结构化绑定也可以正常工作,请参见已接受答案中的代码片段,以获取一个最小示例!

那么,该标准的实现者如何在没有get成员的情况下使结构化绑定适用于元组,以及如何为我的自定义类实现相同的行为?

c++ std stdtuple c++17

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

使用lambda表达式作为比较std :: set,当它在一个向量中时

我想使用lambda表达式作为std ::整数集的自定义比较.该网站上有许多解释如何执行此操作的答案,例如/sf/answers/3228982501/.事实上,

#include <vector>
#include <set>
#include <iostream>

int main() {

    auto different_cmp = [](int i, int j) -> bool {
        return j < i;
    };

    std::set<int, decltype(different_cmp)> integers(different_cmp);

    integers.insert(3);
    integers.insert(4);
    integers.insert(1);
    for (int integer : integers) {
        std::cout << integer << " ";
    }

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

编制和输出

4 3 1

正如所料.但是,当我尝试将此设置放在矢量中时

    std::vector<std::set<int, decltype(different_cmp)>> vec_of_integers;
    vec_of_integers.push_back(integers);
Run Code Online (Sandbox Code Playgroud)

编译器抱怨.我正在使用Visual Studio 2017,我根据周围的代码得到不同的编译器错误.在上面的例子中,它是

1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\utility(77): error C2664: 'void std::swap(std::exception_ptr &,std::exception_ptr &) noexcept': cannot convert argument 1 from '_Ty' …
Run Code Online (Sandbox Code Playgroud)

c++ lambda stl stdvector stdset

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

从什么意义上说std :: disjunction在compile_time短路

cppreference.com上的描述中,我得到的印象是std :: disjunction旨在使我在编译时短路,因此我可以这样使用它:

#include <type_traits>
#include <iostream>

template<nullptr_t null = nullptr>
constexpr bool does_not_compile() {
    static_assert(null != nullptr);
    return false;
}

void hello_world () {
    if constexpr (std::disjunction_v<std::true_type, std::bool_constant<does_not_compile()>>) {
        std::cout << "Hello World!" << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这不会编译,在上述static_assert不会触发的意义上,std :: disjunction不会短路(实时示例)。

但是,那是什么意思呢?这不是||的通常行为 在运行时,因为必须在编译时知道std :: disjunction的类型,这取决于其值。

c++ std variadic-templates c++17 if-constexpr

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