【问题标题】:Size of std::array in class template depending on template parameter类模板中 std::array 的大小取决于模板参数
【发布时间】:2018-08-03 23:44:51
【问题描述】:

我有以下类模板

template<int N>
constexpr int arraySize() { return arraySize<N-1>() + N; }

template<>
constexpr int arraySize<0>() { return 0; }

template<int C>
class MyClass {
    public:
    std::array<int, arraySize<C>()> arr;
};

int main() {

    MyClass<3> cls;
    std::cout << cls.arr.size() << std::endl;    // Output: 6
}

一切正常,但我想将calculateArraySize&lt;N&gt;() 作为成员函数。我尝试了以下方法:

template<int C>
class MyClass {
    public:

    static constexpr int arraySize();
    std::array<int, MyClass<C>::arraySize()> arr;
};

template<int C>
constexpr int MyClass<C>::arraySize(){ return MyClass<C-1>::arraySize() + C; }

template<>
constexpr int MyClass<0>::arraySize() { return 0; }

导致以下错误:

致命错误:递归模板实例化超出最大值 深度 1024 std::array::arraySize()> arr;

template<int C>
class MyClass {
    public:

    template<int N>
    static constexpr int arraySize();
    std::array<int, MyClass::arraySize<C>()> arr;
};

template<int C>
template<int N>
constexpr int MyClass<C>::arraySize(){ return MyClass::arraySize<N-1>() + N-1; }

template<int C>
template<>
constexpr int MyClass<C>::arraySize<0>() { return 0; }

给出以下错误:

tmp.cc:19:27: 错误:不能专门化(使用'template')一个成员 非专业模板 constexpr int MyClass::arraySize() { return 0; }

是否有可能实现所需的行为?欢迎使用 C++14/C++17 功能的解决方案(我想应该可以使用 if-constexpr),但由于只有 C++11 可用,因此无法解决我的特定问题。

【问题讨论】:

  • 提示:第一个N自然数之和(所以1+2+3+...+N)是N*(N+1)/2
  • @FrançoisAndrieux 是的,我知道,谢谢。我的问题不仅仅是关于这个特殊情况,它更像是一个简单的例子。
  • 那我不清楚你在问什么。如果问题是您超出了最大深度,那么第一个解决方案是减少递归深度。您是在问如何专门化成员函数?
  • 如果不专门化整个类,就不能专门化 C++ 中的成员函数。
  • 第二个错误表明了这一点。有什么解决方法吗?

标签: c++ c++11 templates


【解决方案1】:

您可以将函数移动到类中,并针对基本案例专门化整个类。看起来像:

template<int C>
class MyClass {
    public:

    static constexpr int arraySize(){ return MyClass<C-1>::arraySize() + C; }
    std::array<int, MyClass<C>::arraySize()> arr;
};

template<>
class MyClass<0> {
    public:
    static constexpr int arraySize(){ return 0; }
};

int main() {
    MyClass<3> cls;
    std::cout << cls.arr.size() << std::endl;    // Output: 6
}

Live Example

【讨论】:

  • @datell,请记住,此专业化不会从模板继承任何内容。即,例如,如果您的模板类 MyClass&lt;C&gt; 有一个成员 int blah,那么所写的专业化 MyClass&lt;C&gt; 将没有这个成员。
【解决方案2】:

您也可以使用成员变量代替成员函数。

template <int C>
class MyClass {
   public:

      static constexpr int array_size = MyClass<C-1>::array_size + C;
      std::array<int, array_size> arr;
};

template <>
class MyClass<0> {
   public:
       static constexpr int array_size = 0;
};

【讨论】:

    猜你喜欢
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 1970-01-01
    • 2017-04-18
    • 2012-07-02
    • 1970-01-01
    • 2019-04-07
    相关资源
    最近更新 更多