简体   繁体   English

模板元编程静态成员函数无法获取类的const静态值

[英]template metaprogramming static member function cannot get const static value of class

I am trying to generate numbers in compile time and tried templates. 我正在尝试在编译时生成数字并尝试使用模板。 But when I use constexpr static member variable instead of enum , and in a static member function where I try to push it into a std::vector , the compiler told me the linker was unable to link. 但是,当我使用constexpr static成员变量而不是enum ,并且在一个static成员函数中尝试将其推入std::vector ,编译器告诉我链接器无法链接。

For example, here is a simple program to calculate factorial of n . 例如,这是一个计算n阶乘的简单程序。

#include <iostream>
#include <vector>

template <uint64_t n> struct factorial {
    constexpr static uint64_t value = factorial<n - 1>::value * n;
    static void put(std::vector<uint64_t> &v) {
        factorial<n - 1>::put(v);
        v.push_back(value);
    }
};

template <> struct factorial<0> {
    constexpr static uint64_t value = 1;
    static void put(std::vector<uint64_t> &v) {
        v.push_back(1);
    }
};

int main() {
    using namespace std;
    vector<uint64_t> v;
    factorial<10>::put(v);
    for (auto fact: v)
        cout << fact << endl;
    return 0;
}

This will produce link fail information with both g++ 7.1 and clang 4.0, so I thought it was not a bug. 这将产生g ++ 7.1和clang 4.0的链接失败信息,因此我认为这不是错误。 And when I change constexpr static to enum like 当我将constexpr static更改为enum

template <uint64_t n> struct factorial {
    enum { value = factorial<n - 1>::value * n };
    static void put(std::vector<uint64_t> &v) {
        factorial<n - 1>::put(v);
        v.push_back(value);
    }
};

template <> struct factorial<0> {
    enum { value = 1 };
    static void put(std::vector<uint64_t> &v) {
        v.push_back(1);
    }
};

It compiles and links and runs pretty well. 它可以编译,链接并运行得很好。

I am wondering whether C++ standards mentioned about this. 我想知道C ++标准是否提到了这一点。

As far as I can tell it's because std::vector<T>::push_back() has the signature 据我所知,这是因为std::vector<T>::push_back()具有签名
void push_back(V const&) . void push_back(V const&)

Therefore a reference is being taken of value. 因此,参考是有价值的。

Therefore it must have an address, which it does not because it is never defined (although this seems a little illogical to me) - perhaps this gets fixed in c++17? 因此,它必须有一个地址,它不是因为从未定义过而没有(尽管这对我来说似乎有点不合逻辑)-也许这在c ++ 17中已得到解决?

It can be made to compile by taking a copy and pushing that: 可以通过复制并推送以下内容来进行编译:

#include <iostream>
#include <vector>

template <uint64_t n> struct factorial {
    constexpr static uint64_t value = factorial<n - 1>::value * n;
    static void put(std::vector<uint64_t> &v) {
        factorial<n - 1>::put(v);
        auto vcpy = value;   // *** HERE ***
        v.push_back(vcpy);
    }
};

template <> struct factorial<0> {
    constexpr static uint64_t value = 1;
    static void put(std::vector<uint64_t> &v) {
        v.push_back(1);
    }
};

int main() {
    using namespace std;
    vector<uint64_t> v;
    factorial<10>::put(v);
    for (auto fact: v)
        cout << fact << endl;
    return 0;
}

Try (in your first example) adding 尝试(在第一个示例中)添加

template <uint64_t n>
constexpr uint64_t factorial<n>::value;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM