标签: c++14

如何在使用原始存储时模拟EBO?

我有一个我在实现低级泛型类型时使用的组件,它存储任意类型的对象(可能是也可能不是类类型),它可能是空的,以利用空基本优化:

template <typename T, unsigned Tag = 0, typename = void>
class ebo_storage {
  T item;
public:
  constexpr ebo_storage() = default;

  template <
    typename U,
    typename = std::enable_if_t<
      !std::is_same<ebo_storage, std::decay_t<U>>::value
    >
  > constexpr ebo_storage(U&& u)
    noexcept(std::is_nothrow_constructible<T,U>::value) :
    item(std::forward<U>(u)) {}

  T& get() & noexcept { return item; }
  constexpr const T& get() const& noexcept { return item; }
  T&& get() && noexcept { return std::move(item); }
};

template <typename T, unsigned Tag>
class ebo_storage<
  T, Tag, std::enable_if_t<std::is_class<T>::value>
> : …
Run Code Online (Sandbox Code Playgroud)

c++ c++14

79
推荐指数
1
解决办法
1850
查看次数

error :: make_unique不是'std'的成员

我正在尝试编译代码审查上发布的以下线程池程序来测试它.

https://codereview.stackexchange.com/questions/55100/platform-independant-thread-pool-v4

但我得到了错误

threadpool.hpp: In member function ‘std::future<decltype (task((forward<Args>)(args)...))> threadpool::enqueue_task(Func&&, Args&& ...)’:
threadpool.hpp:94:28: error: ‘make_unique’ was not declared in this scope
     auto package_ptr = make_unique<task_package_impl<R, decltype(bound_task)>>  (std::move(bound_task), std::move(promise));
                        ^
threadpool.hpp:94:81: error: expected primary-expression before ‘>’ token
     auto package_ptr = make_unique<task_package_impl<R, decltype(bound_task)>>(std::move(bound_task), std::move(promise));
                                                                             ^
main.cpp: In function ‘int main()’:
main.cpp:9:17: error: ‘make_unique’ is not a member of ‘std’
 auto ptr1 = std::make_unique<unsigned>();
             ^
main.cpp:9:34: error: expected primary-expression before ‘unsigned’
 auto ptr1 = std::make_unique<unsigned>();
                              ^
main.cpp:14:17: error: ‘make_unique’ is not a member …
Run Code Online (Sandbox Code Playgroud)

c++ compiler-errors unique-ptr c++11 c++14

77
推荐指数
3
解决办法
8万
查看次数

尽管在右侧有例外,但C++中的赋值仍然发生

我有一些(C++ 14)代码,如下所示:

map<int, set<string>> junk;
for (int id : GenerateIds()) {
    try {
        set<string> stuff = GetStuff();
        junk[id] = stuff;
    } catch (const StuffException& e) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

这有效.有时GetStuff()抛出一个异常,这很好,因为如果它,我不想在垃圾地图中的值.

但起初我在循环中写了这个,这不起作用:

junk[id] = GetStuff();
Run Code Online (Sandbox Code Playgroud)

更确切地说,即使GetStuff()抛出异常,junk[id]也会创建(并分配一个空集).

这不是我所期望的:我希望它们以相同的方式运行.

我在这里误解了C++的原理吗?

c++ c++14

72
推荐指数
3
解决办法
4065
查看次数

C++中的Lambda-Over-Lambda 14

以下递归lambda调用如何结束/终止?

#include <cstdio>

auto terminal = [](auto term)            // <---------+  
{                                        //           |
    return [=] (auto func)               //           |  ???
    {                                    //           |
        return terminal(func(term));     // >---------+
    };
};


auto main() -> int
{
    auto hello =[](auto s){ fprintf(s,"Hello\n"); return s; };
    auto world =[](auto s){ fprintf(s,"World\n"); return s; };


    terminal(stdout)
            (hello)
            (world) ;

    return 0;

}
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?

Running code

c++ lambda c++14

69
推荐指数
5
解决办法
4215
查看次数

链接C++ 17,C++ 14和C++ 11对象是否安全

假设我有三个编译对象,都是由相同的编译器/版本生成的:

  1. A是用C++ 11标准编译的
  2. B是用C++ 14标准编译的
  3. C是用C++ 17标准编译的

为简单起见,我们假设所有头文件都是用C++ 11编写的,只使用其语义在所有三个标准版本之间没有变化的构造,因此任何相互依赖性都用头包含正确表达,编译器没有反对.

这些对象的组合是什么,链接到单个二进制文件是不安全的?为什么?


编辑:欢迎涵盖主要编译器(例如gcc,clang,vs ++)的答案

c++ linker abi c++11 c++14

69
推荐指数
2
解决办法
6748
查看次数

只使用一个成员的联合的目的是什么?

当我阅读seastar源代码时,我注意到有一个称为tx_side只有一个成员的联合结构。这是解决某些问题的技巧吗?

仅供参考,我将tx_side以下结构粘贴:

union tx_side {
    tx_side() {}
    ~tx_side() {}
    void init() { new (&a) aa; }
    struct aa {
        std::deque<work_item*> pending_fifo;
    } a;
} _tx;
Run Code Online (Sandbox Code Playgroud)

c++ unions c++14

64
推荐指数
1
解决办法
3270
查看次数

为什么没有为C++ 14位分隔符选择空格字符?

从C++ 14开始,感谢n3781(它本身没有回答这个问题),我们可能会编写如下代码:

const int x = 1'234; // one thousand two hundred and thirty four
Run Code Online (Sandbox Code Playgroud)

目的是改进这样的代码:

const int y = 100000000;
Run Code Online (Sandbox Code Playgroud)

并使其更具可读性.

下划线(_)字符已经由用户定义的文本采取了C++ 11,和逗号(,)的本地化问题-许多欧洲国家令人困惑以此作为小数点分隔符-与逗号运算符的冲突,虽然我做的想知道什么样的现实世界的代码可能会被允许,例如1,234,567.

无论如何,更好的解决方案似乎是空间特征:

const int z = 1 000 000;
Run Code Online (Sandbox Code Playgroud)

这些相邻的数字文字标记可以由预处理器连接,就像字符串文字一样:

const char x[5] = "a" "bc" "d";
Run Code Online (Sandbox Code Playgroud)

相反,我们得到了撇号('),我没有被任何我认识为数字分隔符的书写系统使用.

是否有理由选择撇号而不是简单的空间?


令人费解,因为所有这些语言都在文本中保留了一个逗号"分开"一个原本句子的概念,其句号用于"终止"句子 - 至少对我来说,这非常类似于逗号"分开"一个数字的整数部分和一个句号"终止"它为分数输入做好准备.

c++ language-lawyer digit c++14

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

在C++ 14中,C++标准是否在使用不确定值和未定义行为方面发生了变化?

正如初始化所述,需要进行左值到右值的转换?是int x = x;UB吗?C++标准在3.3.2 声明部分中有一个令人惊讶的例子,其中a int用它自己的不确定值初始化:

int x = 12;
{ int x = x; }
Run Code Online (Sandbox Code Playgroud)

这里第二个x用它自己的(不确定的)值初始化.- 结束例子 ]

Johannes对此问题的回答表明是未定义的行为,因为它需要左值到右值的转换.

在最新的C++ 14草案标准中N3936,可以在此处找到此示例已更改为:

unsigned char x = 12;
{ unsigned char x = x; }
Run Code Online (Sandbox Code Playgroud)

这里第二个x用它自己的(不确定的)值初始化.- 结束例子 ]

C++ 14中有关于不确定值和未定义行为的变化,这些变化在示例中引发了这种变化吗?

c++ undefined-behavior language-lawyer c++11 c++14

62
推荐指数
1
解决办法
3991
查看次数

这个元组创作成语有没有名字?

Boost邮件列表中,@ LouisDionne最近发布了以下创建类似元组的实体的巧妙技巧:

#include <iostream>

auto list = [](auto ...xs) { 
    return [=](auto access) { return access(xs...); }; 
}; 

auto length = [](auto xs) { 
    return xs([](auto ...z) { return sizeof...(z); }); 
};

int main()
{
    std::cout << length(list(1, '2', "3")); // 3    
}
Run Code Online (Sandbox Code Playgroud)

实例.

聪明之处在于listlambda采用可变参数列表作为输入,并返回lambda作为输出,将另一个lambda作用于其输入.类似地,lengthlambda是一个类似列表的实体,它将sizeof...向列表的原始输入参数提供可变参数运算符.在sizeof...操作上缠绕有拉姆达的内部,使得它可以被传递给list.

问题:这个元组创作成语是否有名称?也许来自函数式编程语言,其中更常用的是高阶函数.

c++ tuples variadic-templates generic-lambda c++14

62
推荐指数
2
解决办法
4954
查看次数

迭代不同的类型

给出以下代码:

struct Window{
    void show();
    //stuff
}w1, w2, w3;

struct Widget{
    void show();
    //stuff
}w4, w5, w6;

struct Toolbar{
    void show();
    //stuff
}t1, t2, t3;
Run Code Online (Sandbox Code Playgroud)

我想要show一堆物品:

for (auto &obj : {w3, w4, w5, t1})
    obj.show();
Run Code Online (Sandbox Code Playgroud)

然而,这不会编译,因为std::initializer_list<T>for-loop中无法推断T,事实上并没有真正T适合的.我不想创建类型擦除类型,因为需要大量的代码和不必要的运行时开销.如何正确编写循环以便obj分别为概念列表中的每个项推导出类型?

c++ c++11 c++14

62
推荐指数
6
解决办法
5886
查看次数