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