c++ - 参数包和移动语义

标签 c++ c++17 variadic-templates perfect-forwarding

在下面的代码中,尝试通过参数包移动构造失败。

我缺少什么以及如何修复代码以运行所有 4 个变体?

#include <utility>

struct File
{
    File(const char *filename) {}
};

template<typename T>
struct InflateInput
{
    template<typename ...Args>
    InflateInput(int header, Args ...args) : source(args...) {}
    T source;
};

template<typename T>
struct DeflateInput
{
    template<typename ...Args>
    DeflateInput(int level, int header, Args ...args) : source(args...) {}
    DeflateInput(T &&stream, int level, int header) : source(std::move(stream)) {}
    T source;
};

int main()
{
    // case 1: ok
    File file{"filename"};
    DeflateInput deflate1(std::move(file), 5, 0);
    // case 2: ok
    DeflateInput deflate2(File{"filename"}, 5, 0);
    // case 3: error :-(
    InflateInput<DeflateInput<File>> inflate1(0,
        File{"filename"}, 9, 0);
    // case 4: ok
    InflateInput<DeflateInput<File>> inflate2(0,
        9, 0,
        "filename");

    return 0;
};

编译器错误是 (-std=c++2a) 如下:

1.cpp: In instantiation of 'InflateInput<T>::InflateInput(int, Args ...) [with Args = {File, int, int}; T = DeflateInput<File>]':
1.cpp:35:26:   required from here
1.cpp:13:58: error: no matching function for call to 'DeflateInput<File>::DeflateInput(File&, int&, int&)'
   InflateInput(int header, Args ...args) : source(args...) {}
                                                          ^

最佳答案

缺少完美转发。试试下面

template<typename ...Args>
InflateInput(int header, Args&& ...args) : source(std::forward<Args&&>(args)...) {}

下面的构造函数接受 T 类型的右值引用。但是 InflateInput 正在调用一个参数 (Args),它是一个左值。因此编译器错误。

DeflateInput(T &&stream, int level, int header) : source(std::move(stream)) {}

您可以重现相同的错误,例如,

DeflateInput deflate3(file, 5, 0)

https://gcc.godbolt.org/z/Oe2q68

关于c++ - 参数包和移动语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54206926/

相关文章:

c++ - GMock,调用 SaveArg 捕获的 std::function

c++ - 将 Haskell ByteString 转换为 C++ std::string

c++ - MSVC C++ 17 获取词法规范化路径

c++ - 如何避免 C++17 中的虚拟继承?

c++ - 带有可变参数构造函数的好奇 Mixin

c++ - 获取可变参数模板类的第 N 个参数的最简单方法?

C++ 多维数组

c++ - 编译时多个集合的笛卡尔积

c++ - 混合可变参数模板值和可变参数推导类型

c++ - 使用 MPI 的不平衡负载 (v2.0)