首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++在模板化函数中强制std::initializer_list到容器

C++在模板化函数中强制std::initializer_list到容器
EN

Stack Overflow用户
提问于 2018-05-21 15:30:01
回答 1查看 72关注 0票数 1

我无法将初始化程序列表传递给模板函数,然后调用非模板化函数,该函数将强制初始化程序列表到容器。但是,当跳过中间模板函数时,它会编译。

代码语言:javascript
复制
#include <iostream>
#include <vector>

struct MyLoader {
    static auto load(const std::vector<int> &v) {
        return v;
    }
};

template<typename Loader, typename... Args>
auto makeVector(Args&&... args) {
    return Loader::load(std::forward<Args>(args)...);
}

int main() {
    auto v = makeVector<MyLoader>({ 8, 8, 8 });

    for (auto x : v) {
        std::cout << x << "\n";
    }
}

呈现错误:

代码语言:javascript
复制
main.cpp: In instantiation of 'auto makeVector(Args&& ...) [with Loader = MyLoader; Args = {}]':
main.cpp:18:46:   required from here
main.cpp:13:24: error: no matching function for call to 'MyLoader::load()'
     return Loader::load(std::forward<Args>(args)...);
            ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:6:17: note: candidate: 'static auto MyLoader::load(const std::vector<int>&)'
     static auto load(const std::vector<int> &v) {
                 ^~~~
main.cpp:6:17: note:   candidate expects 1 argument, 0 provided
main.cpp: In function 'int main()':
main.cpp:18:46: error: too many arguments to function 'auto makeVector(Args&& ...) [with Loader = MyLoader; Args = {}]'
     auto v = makeVector<MyLoader>({ 8, 8, 8 });
                                              ^
main.cpp:12:6: note: declared here
 auto makeVector(Args&&... args) {
      ^~~~~~~~~~
main.cpp:18:10: error: 'void v' has incomplete type
     auto v = makeVector<MyLoader>({ 8, 8, 8 });
          ^
main.cpp:20:19: error: unable to deduce 'auto&&' from 'v'
     for (auto x : v) {

但是,以下内容编译得非常好:

代码语言:javascript
复制
#include <iostream>
#include <vector>

struct MyLoader {
    static auto load(const std::vector<int> &v) {
        return v;
    }
};

int main() {
    auto v = MyLoader::load({ 8, 8, 8 });

    for (auto x : v) {
        std::cout << x << "\n";
    }
}

为什么在第一个示例中,初始化程序列表没有强制使用MyLoader::load()MyLoader::load()参数?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-21 16:31:24

问题是,{8, 8, 8}并不像类型那样可还原。

如果将它传递给接收const std::vector<int>的方法,一切都会顺利进行,因为编译器知道{8, 8, 8}用于初始化std::vector<int>

但是,如果将它传递给一个函数,该函数接收一个包含Args&&... args未知类型的参数,这是不起作用的,因为编译器不知道女巫类型是{8, 8, 8}

建议:以不同的方式传递值。

代码语言:javascript
复制
auto v = makeVector<MyLoader>(8, 8, 8);

因此编译器可以将Args...检测为int, int, int,并传递给load()添加图。

代码语言:javascript
复制
// ------------------V-----------------------------V   
return Loader::load( { std::forward<Args>(args)... } );

如果你真的(真的!)要将该值作为初始化列表传递给makeVector(),可以作为数组拦截它们。

代码语言:javascript
复制
template <typename Ldr, std::size_t Dim, typename Arg>
auto makeVector (Arg(&&arg)[Dim])

因此,编译器可以推断类型(Arg,作为int)和大小(Dim3{8, 8, 8}的情况下)。

但是要解压缩数组,您需要索引,因此需要一个函数助手。

某物

代码语言:javascript
复制
template <typename Ldr, std::size_t ... Is, std::size_t Dim, typename Arg>
auto makeVectorH (std::index_sequence<Is...> const &, Arg(&&arg)[Dim])
 { return Ldr::load({std::forward<Arg>(arg[Is])...}); }

template <typename Ldr, std::size_t Dim, typename Arg>
auto makeVector (Arg(&&arg)[Dim])
 { return makeVectorH<Ldr>(std::make_index_sequence<Dim>{},
                           std::forward<Arg[Dim]>(arg)); }

下面是一个完整编译数组用例的C++14示例(但我建议更简单地使用各种参数)

代码语言:javascript
复制
#include <vector>
#include <utility>
#include <iostream>

struct MyLoader
 { static auto load(const std::vector<int> &v) { return v; } };

template <typename Ldr, std::size_t ... Is, std::size_t Dim, typename Arg>
auto makeVectorH (std::index_sequence<Is...> const &, Arg(&&arg)[Dim])
 { return Ldr::load({std::forward<Arg>(arg[Is])...}); }

template <typename Ldr, std::size_t Dim, typename Arg>
auto makeVector (Arg(&&arg)[Dim])
 { return makeVectorH<Ldr>(std::make_index_sequence<Dim>{},
                           std::forward<Arg[Dim]>(arg)); }

int main ()
 {
   auto v = makeVector<MyLoader>({8, 8, 8});

   for (auto x : v)
        std::cout << x << "\n";
 }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50452070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档