小编Vit*_*meo的帖子

两侧都带有省略号的Lambda Pack捕获-是什么意思?

批准用于C ++ 20的P0780 (“允许在lambda init-capture中扩展包”)允许通过...在包扩展之前放置省略号()来生成闭合数据包,作为lambda捕获的一部分。

这很有用-例如-在通过移动捕获包时:

template <typename... Ts>
void foo(Ts... xs)
{
    bar([...xs = std::move(xs)]{ /* ... */ });
}
Run Code Online (Sandbox Code Playgroud)

在试用此功能时,我想到了这个神秘的构造:

template <typename... Ts>
void foo(Ts... xs)
{
    [...xs...]{}();
}

int main()
{
    foo(0, 1, 2);
}
Run Code Online (Sandbox Code Playgroud)

Godbolt.org上的实时示例

g ++(trunk)对其进行编译,但是老实说,我一直在努力理解其含义。这是什么意思?生成闭包作为数据成员将具有什么?

c++ lambda variadic-templates c++20

17
推荐指数
1
解决办法
448
查看次数

了解缓存友好,面向数据的对象和句柄

using namespace std;
Run Code Online (Sandbox Code Playgroud)

考虑实体/对象管理的传统OOP方法:

struct Entity { bool alive{true}; }

struct Manager {        
    vector<unique_ptr<Entity>> entities; // Non cache-friendly

    void update() {
        // erase-remove_if idiom: remove all !alive entities
        entities.erase(remove_if(begin(entities), end(entities),
            [](const unique_ptr<Entity>& e){ return !e->alive; }));
    }
};

struct UserObject {
    // Even if Manager::entities contents are re-ordered
    // this reference is still valid (if the entity was not deleted)
    Entity& entity;
};
Run Code Online (Sandbox Code Playgroud)

但是,我想尝试一种面向数据的方法:动态分配Entity实例,而是将它们存储在缓存友好的线性内存中.

struct Manager {
    vector<Entity> entities; // Cache-friendly
    void …
Run Code Online (Sandbox Code Playgroud)

c++ handle data-oriented-design

16
推荐指数
2
解决办法
3415
查看次数

消除类似地图和类似矢量的容器之间的模板特化

template<class> struct Printer;

// I want this to match std::vector (and similar linear containers) 
template<template<class, class...> class T, class TV, class... TS> 
    struct Printer<T<TV, TS...>> { ... };

// I want this to match std::map (and similar map-like containers)
template<template<class, class, class...> class TM, class TK, class TV, typename... TS> 
    struct Printer<TM<TK, TV, TS...>> { ... }

int main() 
{
    // Both of these match the second specialization, which is only intended
    // for std::map (and similar map-like containers)
    Printer<std::vector<int>>::something(); …
Run Code Online (Sandbox Code Playgroud)

c++ templates stl template-specialization c++11

16
推荐指数
1
解决办法
1703
查看次数

使用`std :: enable_if`和非推导的上下文重载函数模板消歧

请考虑以下代码:

template <typename T>
struct dependent_type
{
    using type = T;
};

template <typename T>
auto foo(T) -> std::enable_if_t<std::is_same<T, int>{}>
{
    std::cout << "a\n"; 
}

template<typename T> 
void foo(typename dependent_type<T>::type) 
{
    std::cout << "b\n";
}
Run Code Online (Sandbox Code Playgroud)
  • 第一个重载foo可以T从其调用中推断出来.

  • 的第二过载foo是一个非推测的上下文.

int main()
{    
    foo<int>( 1 );      // prints "b"
    foo<double>( 1.0 ); // prints "b"
    foo( 1 );           // prints "a"
}
Run Code Online (Sandbox Code Playgroud)

为什么foo<int>( 1 )打印"b"而不是"a"?

wandbox示例

c++ templates language-lawyer overload-resolution c++14

16
推荐指数
1
解决办法
403
查看次数

是否允许使用具有相同整数值的枚举专门化模板?

看看这个简单的片段:

enum class Enum1 { Value };
enum class Enum2 { Value };
template <auto> struct Foo;
template <> struct Foo<Enum1::Value> { };
template <> struct Foo<Enum2::Value> { };
Run Code Online (Sandbox Code Playgroud)

Clang编译了这个,但是gcc-7.2失败了:

x.cpp:5:20:错误:重新定义'struct Foo <(Enum1)0>'template <> struct Foo {};

此错误消息似乎无效,如第5行所示Enum2::Value.

哪个编译器正确?这是符合规范的代码吗?

c++ language-lawyer c++17

16
推荐指数
1
解决办法
391
查看次数

了解DEFER和OBSTRUCT宏

我创建了一个小宏元编程库,实现基本的构建体,例如REPEAT(times, x),IF(value, true, false)元组,等等.

我的大多数实现都是通过基于可变参数计数或通过计数器重载宏来实现的:

// Example:
#define REPEAT_0(x) 
#define REPEAT_1(x) x REPEAT_0(x) 
#define REPEAT_2(x) x REPEAT_1(x)
#define REPEAT_3(x) x REPEAT_2(x)
// ...
// (these defines are generated using an external script)
// ...

#define REPEAT(count, x) CAT(REPEAT_, count)(x)
Run Code Online (Sandbox Code Playgroud)

这很好,但我最近遇到了Paul Fultz的一个非常有趣的宏递归实现.

直到延迟表达部分,我没有理解他的文章.

但是,我在理解使用DEFEROBSTRUCT正确使用方面遇到了很多麻烦.

Paul实现了一个非常优雅的版本,REPEAT不需要脚本生成的定义,如下所示:

#define EAT(...)
#define EXPAND(...) __VA_ARGS__
#define WHEN(c) IF(c)(EXPAND, EAT)

#define REPEAT(count, macro, ...) \
    WHEN(count) \
    ( \ …
Run Code Online (Sandbox Code Playgroud)

c++ macros c-preprocessor c++11

15
推荐指数
1
解决办法
2019
查看次数

对于C++ 17中的非标准布局类,`offsetof`是"有条件支持"是什么意思?

C++ 17标准说:

[support.types.layout]

有条件地支持offsetof使用非标准布局类的宏.


[defns.cond.supp]

有条件地支持

程序构造不需要实现支持


我觉得这个定义offsetof不太精确.

  • 这是否意味着我可以安全地尝试在非标准布局类中使用它?

  • "条件支持"与实现定义有何不同?

  • 编译器是否不支持offsetof生成诊断所需的特定类型的类?

c++ offsetof language-lawyer c++17

15
推荐指数
1
解决办法
655
查看次数

为什么构造std :: unique_ptr用于不完整类型编译?

码:

#include <memory>

struct Data;
std::unique_ptr<Data> make_me();

int main()
{
    std::unique_ptr<Data> m = make_me();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当然失败了:

In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-7.1.0/lib/gcc/x86_64-linux-gnu/7.1.0/../../../../include/c++/7.1.0/memory:80:
/opt/compiler-explorer/gcc-7.1.0/include/c++/7.1.0/bits/unique_ptr.h:76:16: error: invalid application of 'sizeof' to an incomplete type 'Data'
        static_assert(sizeof(_Tp)>0,
                      ^~~~~~~~~~~
/opt/compiler-explorer/gcc-7.1.0/include/c++/7.1.0/bits/unique_ptr.h:268:4: note: in instantiation of member function 'std::default_delete<Data>::operator()' requested here
          get_deleter()(__ptr);
          ^
8 : <source>:8:31: note: in instantiation of member function 'std::unique_ptr<Data, std::default_delete<Data> >::~unique_ptr' requested here
    std::unique_ptr<Data> m = make_me();
                              ^
3 : <source>:3:8: note: forward declaration of 'Data' …
Run Code Online (Sandbox Code Playgroud)

c++ templates language-lawyer c++11 c++14

15
推荐指数
2
解决办法
1210
查看次数

C++ 14多态lambda可能存在gcc错误?

我发现了使用多态C++ 14 lambdas(lambdas auto在其参数中)的奇怪行为:


小片0:

#include <iostream>

template<typename T> void doLambda(T&& mFn)
{
  std::forward<T>(mFn)(int{0});
}

template<typename T> void test(T&& mV)
{
    doLambda([&mV](auto mE)
    {
        std::forward<decltype(mV)>(mV);
    });
}

int main() { test(int{0}); return 0; }
Run Code Online (Sandbox Code Playgroud)

clang ++ 3.5.1:代码片段编译并成功运行.

g ++ 4.9.2:代码片段无法编译:

example.cpp:实例化'test(T&&)::<lambda(auto:1)> [with auto:1 = int; T = int]':

5:从'void doLambda(T&&) [with T = test(T&&) [with T = int]::]'
13要求:从'void test(T&&) [with T = int]'
18要求:从这里要求
12:错误:'mV'未在此范围内声明

std::forward<decltype(mV)>(mV);
^

编译失败


小片1:

与代码段0的唯一区别在于 …

c++ lambda gcc clang c++14

14
推荐指数
1
解决办法
404
查看次数

懒惰评估(短路)模板条件类型的通用方法

在使用编译时字符串(可变参数列表char)操作时,我需要实现一种检查编译时字符串是否包含另一个(较小的)编译时字符串的方法.

这是我的第一次尝试:

template<int I1, int I2, typename, typename> struct Contains;

template<int I1, int I2, char... Cs1, char... Cs2> 
struct Contains<I1, I2, CharList<Cs1...>, CharList<Cs2...>>
{
    using L1 = CharList<Cs1...>;
    using L2 = CharList<Cs2...>;
    static constexpr int sz1{L1::size};
    static constexpr int sz2{L2::size};

    using Type = std::conditional
    <
        (I1 >= sz1),
        std::false_type,
        std::conditional
        <
            (L1::template at<I1>() != L2::template at<I2>()),
            typename Contains<I1 + 1, 0, L1, L2>::Type,
            std::conditional
            <
                (I2 == sz2 - 1),
                std::true_type,
                typename Contains<I1 + 1, I2 + 1, …
Run Code Online (Sandbox Code Playgroud)

c++ templates metaprogramming template-meta-programming c++14

14
推荐指数
2
解决办法
309
查看次数