替换非静态非常量变量模板 [英] Replacement for non-static non-const variable templates

查看:27
本文介绍了替换非静态非常量变量模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚打开了一个问题 关于这个 但不幸的是,正如@super 在他的回答中指出的那样,在函数 getArray 中定义 arr static 并不是我想要的.我想要一个类似非静态非常量变量模板的东西,但直到现在,c++ 还不支持它.是否有一些解决方法与非静态非常量变量模板具有相同的效果.

编辑

如果支持,这将是我期望的语法:

#include 模板结构参数{使用 T = T_;静态 constexpr size_t size = size_;};模板结构体{模板std::array啊;模板std::array&getArray()//应生成 Arguments 中所有 args 的特化{返回 arr;}};int main(){Foo<arg<int,10>我的福;myFoo.getArray>()[0] = 1;Foo<arg<int,10>myFoo2;myFoo2.getArray>()[0] = 2;//不应该影响 myFoo 的 arr}

解决方案

这个:

struct Foo{模板std::array啊;};

是不可能的,因为您要求编译器创建一个结构,其中包含未知数量的变量(用作模板参数的每种类型一个).它在变量是静态的时候工作,因为变量在内存中不必彼此相邻,编译器可以在被请求时创建它们.当它们是非静态的时,编译器必须计算出 struct Foo 的内存布局,但它不能这样做,因为它看不到未来或其他源文件.>

但是,您希望参数包Arguments 中的每种类型都有一个变量.你可以做到这一点……用一些奇怪的技巧.每个类型可以有一个基类,每个基类可以有一个变量.这就是像 std::tuplestd::variant 这样的类可能是用你的编译器实现的:

template结构 FooBase{std::array啊;};模板struct Foo : FooBase...{模板std::array&获取数组(){返回 FooBase::arr;//如果 Argument 不在 Arguments 中,则会出错}};

I've just opened a question about this but unfortunately, as @super pointed out in his answer, defining arr static in the function getArray is not what I want. I would like something like a non-static non-const variable template but that specifically is not supported in c++ up until now. Is there some workaround for this which has the same effect as a non-static non-const variable template.

EDIT

This would be how I would expect the syntax to be if it was supported:

#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> arr;
    
    template<typename Argument>
    std::array<typename Argument::T, Argument::size>& getArray() // specializations of all args in Arguments should be generated
    {
        return arr<Argument>;
    }
};

int main()
{
    Foo<arg<int, 10>> myFoo;
    myFoo.getArray<arg<int, 10>>()[0] = 1;
    Foo<arg<int, 10>> myFoo2;
    myFoo2.getArray<arg<int, 10>>()[0] = 2; // should not affect the arr of myFoo
}

解决方案

This:

struct Foo
{
    template<typename Argument>
    std::array<typename Argument::T, Argument::size> arr;
};

is not possible because you are asking the compiler to create a structure with an unknown number of variables in it (one for every type that's used as a template parameter). It works when the variable is static because then the variables don't have to be next to each other in memory and the compiler can just create them when they are requested. When they're non-static, the compiler has to work out the memory layout of struct Foo and it can't do that since it can't see the future, or other source files.

However, you want to have one variable for each type in the parameter pack Arguments. And you can do that... with some weird trickery. You can have one base class per type, and you can have one variable per base class. This is how classes like std::tuple and std::variant are probably implemented with your compiler:

template<typename Argument>
struct FooBase
{
    std::array<typename Argument::T, Argument::size> arr;
};

template<typename... Arguments>
struct Foo : FooBase<Arguments>...
{
    template<typename Argument>
    std::array<typename Argument::T, Argument::size>& getArray()
    {
        return FooBase<Argument>::arr; // will be an error if Argument isn't in Arguments
    }
};

这篇关于替换非静态非常量变量模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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