通过模板专业化获得对类成员的访问权限

Gaining access to class members from template specialization

本文关键字:成员 访问 权限 访问权 专业化      更新时间:2023-10-16

所以,我基本上想在类中"添加"额外的东西,这取决于它与什么模板参数一起使用,然后对它进行别名以获得更好的界面。类似这样的东西:

template<typename T, std::size_t N>
struct basic_foo
{
    T data[N];
};
//what you see as comments is what i tried
template<> //template<typename T, std::size_t N>
struct basic_foo<double, 3> //: public basic_foo<T, N>
{
    void foo_fun() 
    {
        std::cout << "I'm a foo function!"; 
        for (auto i : data) std::cout << i << " ";
    }
};
template<> //template<typename T, std::size_t N>
struct basic_foo<int, 2> //: public basic_foo<T, N>
{
    void bar_fun() 
    {
        std::cout << "I'm a bar function!";
        for (auto i : data) std::cout << i << " ";
    }
};
using foo = basic_foo<double, 3>;
using bar = basic_foo<int, 2>;
int main()
{   
    foo a = { 12.0, 2.4, 3.0 };
    bar b = { 1, 2 };
}

问题是我无法在专业中访问data

有办法做到这一点吗?还是我应该重新思考我的结构性决策?

您的代码现在不编译,因为您的专业中没有data成员。你试图从主模板继承它,但你几乎得到了它

制作一个basic_foo_base类(或struct)模板,在其中存储data和不需要专门化的函数:

template <typename T, std::size_t N>
struct basic_foo_base
{
    T data[N];
};

这只是将_base添加到现有定义的名称中。现在,再次定义basic_foo

template <typename T, std::size_t N>
struct basic_foo : basic_foo_base<T, N>
{
};

这就是专业化的样子:

template <>
// instantiate the base with the same template arguments
struct basic_foo<double, 3> : public basic_foo_base<double, 3>
{
};

我希望我把一切都做好了。

编辑:不,我没有。

由于继承,basic_foo将不再是一个聚合。我们需要添加一些代码,因此初始化:

foo a = { 12.0, 2.4, 3.0 };

再次有效。也就是说,定义一个采用std::initializer_list:的隐式构造函数

basic_foo_base(std::initializer_list<T> const& il)
{
    std::copy(il.begin(), il.end(), std::begin(data));
}

并添加

using basic_foo_base::basic_foo_base;
// or, for the primary template:
using basic_foo_base<T, N>::basic_foo_base;

在所有CCD_ 10s中将该构造函数包括在过载解析中。

工作代码

除了包含data的公共基类之外,您还可以完全专门化:

template<>
struct basic_foo<double, 3>
{
    double data[3]; // Should be here.
    void foo_fun() 
    {
        std::cout << "I'm a foo function!"; 
        for (auto i : data) std::cout << i << " ";
    }
};