[英]Does the constructor not support the specialization of template functions?
我试图让我班的构造函数function成为特化模板function,但是编译失败。 构造函数不支持模板函数特化吗? 如果这样做,我如何将专业化模板 function 添加到我类的构造函数 function 中?
#include <iostream>
#include <vector>
using namespace std;
class Bignum {
private:
vector<char> vec;
public:
template <class Type> Bignum(const vector<Type> &num) {
vec = num;
}
template <class Type> Bignum(Type &num) {
while (num) {
vec.push_back(num % 10);
num /= 10;
}
}
template <> Bignum(const string &str) {
auto __first = str.rbegin();
auto __last = str.rend();
for (auto i = __first; i <= __last; ++i) {
vec.push_back(*i);
}
}
template <class Type> Bignum(const Type *__first, const Type *__last) {
for (const Type *i = __last; i >= __first; --i) {
vec.push_back(*i);
}
}
template<> Bignum(char *__first, char *__last) {
for (char * i = __last; i >= __first; --i) {
vec.push_back(*i - '0');
}
}
Bignum () {
}
friend ostream& operator << (ostream &os, const Bignum &num) {
auto __first = num.vec.rbegin();
auto __last = num.vec.rend();
for (auto i = __first; i < __last; ++i) {
os << (char)(*i + '0') << ' ';
}
os << (char)(*__last + '0') << endl;
return os;
}
size_t size() const {
return vec.size();
}
const char & at(const size_t &pos) const {
return vec.at(vec.size() - pos);
}
const char & operator [] (const size_t &pos) {
return vec.at(pos);
}
};
int main(int argc, const char * argv[]) {
return 0;
}
我在第 29 行收到一个编译错误,显示没有 function 模板匹配 function 模板专业化“Bignum”。
如评论中所述,您只需从不需要成为成员 function 模板的构造函数中删除模板 <>。
但是,考虑如何以更通用的方式完成您可能追求的目标可能会有所帮助。
您实际上打算如何存储数据是令人困惑的,因为您的实现做了不同的事情(有些人希望它以“小端”存储,而其他人希望它以“大端”顺序存储)。 此外,您的某些函数期望数据存储在 [0, 9] 范围内,而其他函数似乎期望数据存储在 ['0', '9'] 范围内。
然而,这些都与我认为的真正问题无关,这是关于构造函数接口的,所以我假设数据存储为 ASCII 数字 ['0', '9'] 并按照它们的顺序存储打印为字符串 - 只是为了挑选一些东西。
我还建议您使用特定的强类型Digit
作为内部表示,这将消除关于含义的所有歧义。 它还会删除所有不需要的转换的更改。
看起来您希望能够从任何可用于创建 char 向量的内容中创建一个 BigNum。
这个构造函数就是这样做的。 请注意,我们明确禁止采用单一整数类型,因为您可以从其中一个创建向量,但它似乎不是您想要的,因为您有另一个似乎采用整数的构造函数。
template <
typename... ArgTs,
std::enable_if_t<
std::is_constructible_v<std::vector<char>, ArgTs...> &&
not ((sizeof...(ArgTs) == 1) && ... && std::is_integral_v<ArgTs>),
bool> = true>
explicit Bignum(ArgTs && ... args)
: vec(std::forward<ArgTs>(args)...)
{
// If not using a strong type, should at least assert that the
// data you get is what you expect.
assert(vec.size() == std::count_if(
vec.begin(),
vec.end(),
[](unsigned char c){ return std::isdigit(c); }));
}
然后,您可以像这样采用任何无符号整数类型(我将其限制为无符号,因为它看起来不像您的代码已准备好处理有符号值)。
template <
typename T,
std::enable_if_t<
std::is_integral_v<T> && std::is_unsigned_v<T>,
bool> = true>
Bignum(T number)
{
while (number) {
vec.push_back((number % 10) + '0');
number /= 10;
}
std::reverse(vec.begin(), vec.end());
}
而且,要接受字符串,您不需要成员 function 模板...
Bignum(std::string_view s)
: Bignum(s.begin(), s.end())
{ }
最后,我鼓励您熟悉标准算法。 例如,
friend std::ostream & operator << (std::ostream & os, Bignum const & num)
{
std::copy(num.vec.begin(), num.vec.end(), std::ostream_iterator<char>(os));
return os;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.