我怎样才能“生成"来自可变参数模板参数的函数的模板规范? [英] How can I "generate" template spezialations for a function from a variadic template argument?

查看:24
本文介绍了我怎样才能“生成"来自可变参数模板参数的函数的模板规范?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我会先展示这个例子然后再解释它:

#include 模板结构参数{使用 T = T_;静态 constexpr size_t size = size_;};模板结构体{模板std::array&getArray()//应生成 Arguments 中所有 args 的特化{静态 std::array啊;返回 arr;}};int main(){Foo, arg, arg我的福;myFoo.getArray>();myFoo.getArray>();//应该返回一个与上面一行不同的数组myFoo.getArray();//不应该工作,因为 argis 没有传递给 Foo}

如果有一个结构arg,它包含如何在getArray 中构造arr 的信息.args 列表被传递给 Foo.现在我希望为 Arguments 中的每个 arg 生成 getArray 的模板特化.如果没有为特定的 arg 生成专门化,我希望发生某种错误.

我怎样才能做到这一点?

解决方案

您可以使用 static_assert 来确保 ArgumentArguments 的一部分带有辅助结构.

#include #include 模板 <typename... T>结构包含;模板 结构体包含: std::false_type {};模板 <typename T, typename U, typename... Rest>结构体包含<T, U, Rest...>: 包含{};模板 <typename T, typename... Rest>结构体包含<T,T,Rest...>: std::true_type {};模板结构参数{使用 T = T_;静态 constexpr std::size_t size = size_;};模板结构体{模板std::array&getArray()//应生成 Arguments 中所有 args 的特化{static_assert(contains<Argument, Arguments...>(), 无效类型");静态 std::array啊;返回 arr;}};int main(){Foo, arg, arg我的福;myFoo.getArray>()[5] = 7;myFoo.getArray>();//应该返回一个与上面一行不同的数组//myFoo.getArray>();//不应该工作,因为 argis 没有传递给 FooFoo, arg, argmyFoo2;std::cout <<myFoo2.getArray>()[5];Foo, arg, argmyFoo3;std::cout <<myFoo3.getArray>()[5];}

还想指出,如代码所示,myFoomyFoo2 返回相同的数组,因为它们是完全相同的类型.

myFoo3 另一方面是一个单独的类型,这意味着 getArray 成员函数是一个单独的函数,并且拥有它自己的相同类型数组的副本.>

I think I will first show the example and then explain it:

#include <array>

template<typename T_, size_t size_>
struct arg
{
    using T = T_;
    static constexpr size_t size = size_;
};

template<typename... Arugments>
struct Foo
{
    template<typename Argument>
    std::array<typename Argument::T, Argument::size>& getArray() // specializations of all args in Arguments should be generated
    {
        static std::array<typename Argument::T, Argument::size> arr;
        return arr;
    }
};

int main()
{
    Foo<arg<int, 10>, arg<float, 10>, arg<float, 1>> myFoo;
    myFoo.getArray<arg<int, 10>>();
    myFoo.getArray<arg<float, 10>>(); // should return a different array than the line above
    myFoo.getArray<arg<bool, 1>>(); // should NOT work because arg<bool, 10> is was not passed to Foo
}

If got a struct arg which contains the information how to construct arr in getArray. A list of args is passed to Foo. Now I want that template specializations of getArray to be generated for each arg in Arguments. If no specialization was generated for a specific arg I want that some kind of error occurs.

How could I achieve this?

解决方案

You can use static_assert to make sure Argument is part of Arguments with a helper struct.

#include <array>
#include <iostream>

template <typename... T>
struct contains;

template <typename T>
struct contains<T> : std::false_type {};

template <typename T, typename U, typename... Rest>
struct contains<T, U, Rest...> : contains<T, Rest...>  {};

template <typename T, typename... Rest>
struct contains<T, T, Rest...> : std::true_type {};

template<typename T_, std::size_t size_>
struct arg
{
    using T = T_;
    static constexpr std::size_t size = size_;
};

template<typename... Arguments>
struct Foo
{
    template<typename Argument>
    std::array<typename Argument::T, Argument::size>& getArray() // specializations of all args in Arguments should be generated
    {
        static_assert(contains<Argument, Arguments...>(), "Invalid type");
        static std::array<typename Argument::T, Argument::size> arr;
        return arr;
    }
};

int main()
{
    Foo<arg<int, 10>, arg<float, 10>, arg<float, 1>> myFoo;
    myFoo.getArray<arg<int, 10>>()[5] = 7;
    myFoo.getArray<arg<float, 10>>(); // should return a different array than the line above
    //myFoo.getArray<arg<bool, 1>>(); // should NOT work because arg<bool, 10> is was not passed to Foo

    Foo<arg<int, 10>, arg<float, 10>, arg<float, 1>> myFoo2;
    std::cout << myFoo2.getArray<arg<int, 10>>()[5];

    Foo<arg<int, 10>, arg<float, 10>, arg<double, 1>> myFoo3;
    std::cout << myFoo3.getArray<arg<int, 10>>()[5];
}

Just wanted to also point out that as demonstrated by the code, myFoo and myFoo2 returns the same array since they are the exact same type.

myFoo3 on the other hand is a separate type, which means the getArray member function is a separate function and has it's own copy of the same type array.

这篇关于我怎样才能“生成"来自可变参数模板参数的函数的模板规范?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆