[英]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.