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.
For example, here is a simple program to calculate factorial of 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. And when I change constexpr static
to enum
like
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.
Aucun commentaire:
Enregistrer un commentaire