I am still stuck at using templates inside class. I'm trying to make a BigNumber library in C++ for learning purpose.
my code is:
BigInt.h
Code:
#include <iostream>
#include <string>
/**Specifications:
* stores number as: intgr for int part and dec for decimal part
* member sign is 1 for positive number and -1 for negative and 0 for Not a Number i.e. NaN
* Constructor: can take, int, string(formatted as number), float or double
* operators to define +, -, *, /, %, power(), <<, >>
*/
namespace GG
{
class BigInt
{
public:
/** Default constructor */
BigInt();
template<typename T>
BigInt(const T&);
/** Default destructor */
virtual ~BigInt();
/** Copy constructor
* \param other Object to copy from
*/
BigInt(const BigInt& other);
/** Assignment operator
* \param other Object to assign from
* \return A reference to this
*/
BigInt& operator=(const BigInt& other);
friend std::ostream& operator<<(std::ostream& os, const BigInt& bigInt);
friend std::istream& operator>>(std::istream& is, BigInt& bigInt);
protected:
private:
/**
* Number is represented as:
* +0.123324 or -0.1232432
* +123 or -123 etc
* [+ or -] then [numbers] then maybe [.] then [more numbers]
*/
std::string intgr; // Integer part of number i.e. 23 in 23.45
std::string dec; // decimal part of number i.e. 45 in 23.45
short sign; // 1 for positive number, -1 for negative and 0 for NaN (Not a Number)
};
template<typename T>
BigInt::BigInt(const T& n)
{
std::string num_str = std::to_string(n); // |note: previous declaration as ‘std::__cxx11::string num_str’|
BigInt(num_str); // |error: conflicting declaration ‘GG::BigInt num_str’|
}
//Specialiazed for string
template<> inline
BigInt::BigInt<std::string>(const std::string& str)
{
BigInt();
}
//Specialized for char
template<> inline
BigInt::BigInt<char>(const char& ch)
{
BigInt();
}
}// namespace GG ends here
#include <iostream>
#include "BigInt.h"
using namespace std;
int main()
{
short short_n = 123;
GG::BigInt n(short_n);
GG::BigInt n_default;
std::cout << n << " " << n_default ;
return 0;
}
I have written all the code for the sake of completeness so that you could reproduce the problem. But you need to look mainly in BigInt.h in which I am facing problem in specialized string contructor.
errors are as follows:
1. ||error: conflicting declaration ‘GG::BigInt num_str’||
2. ||note: previous declaration as ‘std::__cxx11::string num_str’||
Last edited by 2kaud; July 18th, 2017 at 01:13 PM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
Thank you very much, again. It worked.
Now I am having one more problem that when I pass a C style char array to BigInt() it does not catch the specialized string constructor but it goes to generic constructor, what should I do for this.
As a c-style array is of type char *, you can't specialise the template because this is of type T&. So you just need a function overload.
Code:
BigInt(const char*);
...
BigInt::BigInt(const char* str)
{
//Constructor body here
}
...
GG::BigInt cs("123.456");
Last edited by 2kaud; July 18th, 2017 at 04:08 PM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
As a c-style array is of type char *, you can't specialise the template because this is of type T&. So you just need a function overload.
Code:
BigInt(const char*);
...
BigInt::BigInt(const char* str)
{
//Constructor body here
}
...
GG::BigInt cs("123.456");
I have tried this but it is not working. I still get the error:
1. include/BigInt.h||In instantiation of ‘GG::BigInt::BigInt(const T&) [with T = char [43]]’:|
include/BigInt.h|65|error: no matching function for call to ‘to_string(const char [43])’|
#include <iostream>
#include <string>
#include <regex>
/**Specifications:
* stores number as: intgr for int part and dec for decimal part
* member sign is 1 for positive number and -1 for negative and 0 for Not a Number i.e. NaN
* Constructor: can take, int, string(formatted as number), float or double
* operators to define +, -, *, /, %, power(), <<, >>
*/
namespace GG
{
//typedef char CP[43];
#define DEBUG_SYMS
//#undef DEBUG_SYMS
class BigInt
{
public:
/** Default constructor */
BigInt();
template<typename T>
BigInt(const T&);
template<>
BigInt(const std::string& str);
template<>
BigInt(const char& ch);
BigInt(const char *);
/** Default destructor */
virtual ~BigInt();
/** Copy constructor
* \param other Object to copy from
*/
BigInt(const BigInt& other);
/** Assignment operator
* \param other Object to assign from
* \return A reference to this
*/
BigInt& operator=(const BigInt& other);
friend std::ostream& operator<<(std::ostream& os, const BigInt& bigInt);
friend std::istream& operator>>(std::istream& is, BigInt& bigInt);
protected:
private:
/**
* Number is represented as:
* +0.123324 or -0.1232432
* +123 or -123 etc
* [+ or -] then [numbers] then maybe [.] then [more numbers]
*/
std::string intgr; // Integer part of number i.e. 23 in 23.45
std::string dec; // decimal part of number i.e. 45 in 23.45
short sign; // 1 for positive number, -1 for negative and 0 for NaN (Not a Number)
};
template<typename T>
BigInt::BigInt(const T& n) : BigInt(std::to_string(n))
{
// many many thanks to 2kaud at forums.codeguru.com to make it work
}
//Specialiazed for string
template<>
BigInt::BigInt(const std::string& str)
{
#ifdef DEBUG_SYMS
std::cout << "string constructor called.\n";
#endif
std::string temp = str;
for (int i = temp.find('_'); i != -1; i = temp.find('_'))
{
int j;
for (j = 0; temp[i + j] == '_'; ++j);
temp = temp.substr(0, i) + temp.substr(i + j);
}
int last_zero, first_zero;
std::regex re("([-+]?[0-9]*[.]?[0-9]+)");
std::smatch m;
if (std::regex_match(temp, m, re))
{
#ifdef DEBUG_SYMS
std::cout << "matched.\n";
#endif
if (temp[0] == '-')
{
sign = -1;
temp = temp.substr(1);
}
else
{
sign = 1;
if (temp[0] == '+')
temp = temp.substr(1);
}
// At this point we have signs removed from the string
// now temp has our number but without sign
int dec_pos = temp.find('.');
if (dec_pos == 0)
{
intgr = "0";
dec = temp.substr(dec_pos);
} //end of if dec_pos == 0
else if (dec_pos == -1) // it means we have a simple int
{
dec = "0";
intgr = temp;
} // end of dec_pos == -1
else
{
intgr = temp.substr(0, dec_pos);
dec = temp.substr(dec_pos + 1);
}
// Now we are goint to remove if there are any leading zeros
// 00000234 becomes 234
if (intgr[0] == '0') // execute only if number is like 0000.. not when just 0
{
first_zero = 0;
while (intgr[first_zero] == '0')
{
++first_zero;
}
if (intgr[first_zero] != '\0')
intgr = intgr.substr(first_zero);
else
intgr = "0";
}
//Now we are going to remove if there are any trailing zeros in decimal part
// so 234000000 becomes 234
last_zero = dec.length() - 1;
while (dec[last_zero] == '0' && last_zero > 0)
--last_zero;
dec = dec.substr(0, last_zero + 1);
// At last check for negative zero
if (intgr == "0" && dec == "0")
sign = 1;
} // end of if regex match
else
{
sign = 0;
intgr = dec = "NaN";
}
}// speciliazed template for string ends here
//Specialized for char
template<>
BigInt::BigInt(const char& ch) : BigInt(std::string(1, ch))
{
}
//Specialized template for char*
BigInt::BigInt(const char *arr)
{
std::cout << "char * constructor called" << std::endl;
}
// BigInt::BigInt(const char arr[])
// {
// std::cout<<"char [] constructor called"<<std::endl;
// }
}// namespace GG ends here
namespace GG
{
#define DEBUG_SYMS
#undef DEBUG_SYMS
BigInt::BigInt()
{
//ctor
dec = "NaN";
intgr = "NaN";
sign = 0;
}
// BigInt::BigInt(const long& n)
// {
// dec = "0"; // since long can't have decimal points
// sign = (n>=0)?1:-1;
// intgr = (n>=0)?std::to_string(n):std::to_string(n).substr(1);
// }
//
// BigInt::BigInt(const long long& n)
// {
// dec = "0"; // since long can't have decimal points
// sign = (n>=0)?1:-1;
// intgr = (n>=0)?std::to_string(n):std::to_string(n).substr(1);
// }
//
// BigInt::BigInt(const int& n)
// {
// dec = "0"; // since long can't have decimal points
// sign = (n>=0)?1:-1;
// intgr = (n>=0)?std::to_string(n):std::to_string(n).substr(1);
// }
//
// BigInt::BigInt(const float& n)
// {
// std::string str = std::to_string(n);
// sign = (n>=0)?1:-1;
// if(n<0)
// str = str.substr(1);
// size_t dec_pos = str.find('.');
// intgr = str.substr(0, dec_pos);
// dec = str.substr(dec_pos + 1);
// // remove trailing zeros in decimal part i.e. make 000000 as 0 and make 123000 as 123
// int last_zero = dec.length() - 1;
// while(dec[last_zero] == '0' && last_zero > 0)
// --last_zero;
// dec = dec.substr(0, last_zero + 1);
//
// }
//
// BigInt::BigInt(const double& n)
// {
// std::string str = std::to_string(n);
// sign = (n>=0)?1:-1;
// if(n<0)
// str = str.substr(1);
// size_t dec_pos = str.find('.');
// intgr = str.substr(0, dec_pos);
// dec = str.substr(dec_pos + 1);
// // remove trailing zeros in decimal part i.e. make 000000 as 0 and make 123000 as 123
// int last_zero = dec.length() - 1;
// while(dec[last_zero] == '0' && last_zero > 0)
// --last_zero;
// dec = dec.substr(0, last_zero + 1);
// }
//
// BigInt::BigInt(const long double& n)
// {
// std::string str = std::to_string(n);
// sign = (n>=0)?1:-1;
// if(n<0)
// str = str.substr(1);
// size_t dec_pos = str.find('.');
// intgr = str.substr(0, dec_pos);
// dec = str.substr(dec_pos + 1);
// // remove trailing zeros in decimal part i.e. make 000000 as 0 and make 123000 as 123
// int last_zero = dec.length() - 1;
// while(dec[last_zero] == '0' && last_zero > 0)
// --last_zero;
// dec = dec.substr(0, last_zero + 1);
// }
//
// BigInt::BigInt(const std::string& str)
// {
// #ifdef DEBUG_SYMS
// std::cout<<"string constructor called.\n";
// #endif
//
// std::string temp = str;
// for( int i = temp.find('_'); i!= -1; i=temp.find('_'))
// {
// int j;
// for( j = 0; temp[i+j]=='_'; ++j);
// temp = temp.substr(0, i) + temp.substr(i+j);
// }
// int last_zero, first_zero;
//
// std::regex re("([-+]?[0-9]*[.]?[0-9]+)");
// std::smatch m;
//
// if (std::regex_match(temp, m, re))
// {
// #ifdef DEBUG_SYMS
// std::cout<<"matched.\n";
// #endif
// if(temp[0] == '-')
// {
// sign = -1;
// temp = temp.substr(1);
// }
// else
// {
// sign = 1;
// if(temp[0] == '+')
// temp = temp.substr(1);
// }
// // At this point we have signs removed from the string
// // now temp has our number but without sign
// int dec_pos = temp.find('.');
// if(dec_pos == 0)
// {
// intgr = "0";
// dec = temp.substr(dec_pos);
//
//
// } //end of if dec_pos == 0
// else if(dec_pos == -1) // it means we have a simple int
// {
// dec = "0";
// intgr = temp;
//
// } // end of dec_pos == -1
//
// else
// {
// intgr = temp.substr(0, dec_pos);
// dec = temp.substr(dec_pos + 1);
// }
//
// // Now we are goint to remove if there are any leading zeros
// // 00000234 becomes 234
// if(intgr[0] == '0') // execute only if number is like 0000.. not when just 0
// {
// first_zero = 0;
// while(intgr[first_zero] == '0')
// {
// ++first_zero;
// }
// if(intgr[first_zero] != '\0')
// intgr = intgr.substr(first_zero);
// else
// intgr = "0";
//
// }
//
// //Now we are going to remove if there are any trailing zeros in decimal part
// // so 234000000 becomes 234
// last_zero = dec.length() - 1;
// while(dec[last_zero] == '0' && last_zero > 0)
// --last_zero;
// dec = dec.substr(0, last_zero + 1);
//
// // At last check for negative zero
// if( intgr == "0" && dec == "0")
// sign = 1;
//
// } // end of if regex match
//
// else
// {
// sign = 0;
// intgr = dec = "NaN";
// }
// }
//
// BigInt::BigInt(const char& ch)
// {
// if(ch >='0' && ch<='9')
// {
// intgr = std::string(1, ch);
// dec = "0";
// sign = 1;
// }
// else
// {
// intgr = dec = "NaN";
// sign = 0;
// }
// }
BigInt::~BigInt()
{
//dtor
}
BigInt::BigInt(const BigInt& other)
{
//copy ctor
}
BigInt& BigInt::operator=(const BigInt& rhs)
{
if (this == &rhs) return *this; // handle self assignment
//assignment operator
this->intgr = rhs.intgr;
this->dec = rhs.dec;
this->sign = rhs.sign;
return *this;
}
std::ostream& operator<<(std::ostream& os, const BigInt& bigInt)
{
std::string num_str = "";
if (bigInt.sign == 0)
{
os << "NaN";
return os;
}
else if (bigInt.sign == -1)
num_str = "-";
num_str += bigInt.intgr;
if (bigInt.dec != "0")
{
num_str += ".";
num_str += bigInt.dec;
}
os << num_str;
return os;
}
std::istream& operator>>(std::istream& is, BigInt& bigInt)
{
std::string input_num;
is >> input_num;
bigInt = BigInt(input_num);
return is;
}
}// namespace GG ends here
int main()
{
using namespace std::string_literals;
char arr[] = "_-____20__999_______343_453_100_000_00____";
short short_n = 123;
GG::BigInt n(short_n);
GG::BigInt n_default;
GG::BigInt str_n('1');
GG::BigInt strstr("123"s);
GG::BigInt char_arr_n(arr);
std::cout << n << " " << n_default << " " << str_n << " " << char_arr_n << std::endl;
GG::BigInt input;
std::cout << "Input a number: ";
std::cin >> input;
std::cout << input;
return 0;
}
When run, displays
Code:
string constructor called.
matched.
string constructor called.
matched.
string constructor called.
matched.
char * constructor called
123 NaN 1 NaN
Input a number:
as I defined DEBUG_SYMS
PS There's no need to attribute me in the code.
Last edited by 2kaud; July 19th, 2017 at 03:55 AM.
Reason: PS
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
#include <iostream>
#include <string>
#include <regex>
/**Specifications:
* stores number as: intgr for int part and dec for decimal part
* member sign is 1 for positive number and -1 for negative and 0 for Not a Number i.e. NaN
* Constructor: can take, int, string(formatted as number), float or double
* operators to define +, -, *, /, %, power(), <<, >>
*/
namespace GG
{
//typedef char CP[43];
#define DEBUG_SYMS
//#undef DEBUG_SYMS
class BigInt
{
public:
/** Default constructor */
BigInt();
template<typename T>
BigInt(const T&);
template<>
BigInt(const std::string& str);
template<>
BigInt(const char& ch);
BigInt(const char *);
/** Default destructor */
virtual ~BigInt();
/** Copy constructor
* \param other Object to copy from
*/
BigInt(const BigInt& other);
/** Assignment operator
* \param other Object to assign from
* \return A reference to this
*/
BigInt& operator=(const BigInt& other);
friend std::ostream& operator<<(std::ostream& os, const BigInt& bigInt);
friend std::istream& operator>>(std::istream& is, BigInt& bigInt);
protected:
private:
/**
* Number is represented as:
* +0.123324 or -0.1232432
* +123 or -123 etc
* [+ or -] then [numbers] then maybe [.] then [more numbers]
*/
std::string intgr; // Integer part of number i.e. 23 in 23.45
std::string dec; // decimal part of number i.e. 45 in 23.45
short sign; // 1 for positive number, -1 for negative and 0 for NaN (Not a Number)
};
template<typename T>
BigInt::BigInt(const T& n) : BigInt(std::to_string(n))
{
// many many thanks to 2kaud at forums.codeguru.com to make it work
}
//Specialiazed for string
template<>
BigInt::BigInt(const std::string& str)
{
#ifdef DEBUG_SYMS
std::cout << "string constructor called.\n";
#endif
std::string temp = str;
for (int i = temp.find('_'); i != -1; i = temp.find('_'))
{
int j;
for (j = 0; temp[i + j] == '_'; ++j);
temp = temp.substr(0, i) + temp.substr(i + j);
}
int last_zero, first_zero;
std::regex re("([-+]?[0-9]*[.]?[0-9]+)");
std::smatch m;
if (std::regex_match(temp, m, re))
{
#ifdef DEBUG_SYMS
std::cout << "matched.\n";
#endif
if (temp[0] == '-')
{
sign = -1;
temp = temp.substr(1);
}
else
{
sign = 1;
if (temp[0] == '+')
temp = temp.substr(1);
}
// At this point we have signs removed from the string
// now temp has our number but without sign
int dec_pos = temp.find('.');
if (dec_pos == 0)
{
intgr = "0";
dec = temp.substr(dec_pos);
} //end of if dec_pos == 0
else if (dec_pos == -1) // it means we have a simple int
{
dec = "0";
intgr = temp;
} // end of dec_pos == -1
else
{
intgr = temp.substr(0, dec_pos);
dec = temp.substr(dec_pos + 1);
}
// Now we are goint to remove if there are any leading zeros
// 00000234 becomes 234
if (intgr[0] == '0') // execute only if number is like 0000.. not when just 0
{
first_zero = 0;
while (intgr[first_zero] == '0')
{
++first_zero;
}
if (intgr[first_zero] != '\0')
intgr = intgr.substr(first_zero);
else
intgr = "0";
}
//Now we are going to remove if there are any trailing zeros in decimal part
// so 234000000 becomes 234
last_zero = dec.length() - 1;
while (dec[last_zero] == '0' && last_zero > 0)
--last_zero;
dec = dec.substr(0, last_zero + 1);
// At last check for negative zero
if (intgr == "0" && dec == "0")
sign = 1;
} // end of if regex match
else
{
sign = 0;
intgr = dec = "NaN";
}
}// speciliazed template for string ends here
//Specialized for char
template<>
BigInt::BigInt(const char& ch) : BigInt(std::string(1, ch))
{
}
//Specialized template for char*
BigInt::BigInt(const char *arr)
{
std::cout << "char * constructor called" << std::endl;
}
// BigInt::BigInt(const char arr[])
// {
// std::cout<<"char [] constructor called"<<std::endl;
// }
}// namespace GG ends here
namespace GG
{
#define DEBUG_SYMS
#undef DEBUG_SYMS
BigInt::BigInt()
{
//ctor
dec = "NaN";
intgr = "NaN";
sign = 0;
}
// BigInt::BigInt(const long& n)
// {
// dec = "0"; // since long can't have decimal points
// sign = (n>=0)?1:-1;
// intgr = (n>=0)?std::to_string(n):std::to_string(n).substr(1);
// }
//
// BigInt::BigInt(const long long& n)
// {
// dec = "0"; // since long can't have decimal points
// sign = (n>=0)?1:-1;
// intgr = (n>=0)?std::to_string(n):std::to_string(n).substr(1);
// }
//
// BigInt::BigInt(const int& n)
// {
// dec = "0"; // since long can't have decimal points
// sign = (n>=0)?1:-1;
// intgr = (n>=0)?std::to_string(n):std::to_string(n).substr(1);
// }
//
// BigInt::BigInt(const float& n)
// {
// std::string str = std::to_string(n);
// sign = (n>=0)?1:-1;
// if(n<0)
// str = str.substr(1);
// size_t dec_pos = str.find('.');
// intgr = str.substr(0, dec_pos);
// dec = str.substr(dec_pos + 1);
// // remove trailing zeros in decimal part i.e. make 000000 as 0 and make 123000 as 123
// int last_zero = dec.length() - 1;
// while(dec[last_zero] == '0' && last_zero > 0)
// --last_zero;
// dec = dec.substr(0, last_zero + 1);
//
// }
//
// BigInt::BigInt(const double& n)
// {
// std::string str = std::to_string(n);
// sign = (n>=0)?1:-1;
// if(n<0)
// str = str.substr(1);
// size_t dec_pos = str.find('.');
// intgr = str.substr(0, dec_pos);
// dec = str.substr(dec_pos + 1);
// // remove trailing zeros in decimal part i.e. make 000000 as 0 and make 123000 as 123
// int last_zero = dec.length() - 1;
// while(dec[last_zero] == '0' && last_zero > 0)
// --last_zero;
// dec = dec.substr(0, last_zero + 1);
// }
//
// BigInt::BigInt(const long double& n)
// {
// std::string str = std::to_string(n);
// sign = (n>=0)?1:-1;
// if(n<0)
// str = str.substr(1);
// size_t dec_pos = str.find('.');
// intgr = str.substr(0, dec_pos);
// dec = str.substr(dec_pos + 1);
// // remove trailing zeros in decimal part i.e. make 000000 as 0 and make 123000 as 123
// int last_zero = dec.length() - 1;
// while(dec[last_zero] == '0' && last_zero > 0)
// --last_zero;
// dec = dec.substr(0, last_zero + 1);
// }
//
// BigInt::BigInt(const std::string& str)
// {
// #ifdef DEBUG_SYMS
// std::cout<<"string constructor called.\n";
// #endif
//
// std::string temp = str;
// for( int i = temp.find('_'); i!= -1; i=temp.find('_'))
// {
// int j;
// for( j = 0; temp[i+j]=='_'; ++j);
// temp = temp.substr(0, i) + temp.substr(i+j);
// }
// int last_zero, first_zero;
//
// std::regex re("([-+]?[0-9]*[.]?[0-9]+)");
// std::smatch m;
//
// if (std::regex_match(temp, m, re))
// {
// #ifdef DEBUG_SYMS
// std::cout<<"matched.\n";
// #endif
// if(temp[0] == '-')
// {
// sign = -1;
// temp = temp.substr(1);
// }
// else
// {
// sign = 1;
// if(temp[0] == '+')
// temp = temp.substr(1);
// }
// // At this point we have signs removed from the string
// // now temp has our number but without sign
// int dec_pos = temp.find('.');
// if(dec_pos == 0)
// {
// intgr = "0";
// dec = temp.substr(dec_pos);
//
//
// } //end of if dec_pos == 0
// else if(dec_pos == -1) // it means we have a simple int
// {
// dec = "0";
// intgr = temp;
//
// } // end of dec_pos == -1
//
// else
// {
// intgr = temp.substr(0, dec_pos);
// dec = temp.substr(dec_pos + 1);
// }
//
// // Now we are goint to remove if there are any leading zeros
// // 00000234 becomes 234
// if(intgr[0] == '0') // execute only if number is like 0000.. not when just 0
// {
// first_zero = 0;
// while(intgr[first_zero] == '0')
// {
// ++first_zero;
// }
// if(intgr[first_zero] != '\0')
// intgr = intgr.substr(first_zero);
// else
// intgr = "0";
//
// }
//
// //Now we are going to remove if there are any trailing zeros in decimal part
// // so 234000000 becomes 234
// last_zero = dec.length() - 1;
// while(dec[last_zero] == '0' && last_zero > 0)
// --last_zero;
// dec = dec.substr(0, last_zero + 1);
//
// // At last check for negative zero
// if( intgr == "0" && dec == "0")
// sign = 1;
//
// } // end of if regex match
//
// else
// {
// sign = 0;
// intgr = dec = "NaN";
// }
// }
//
// BigInt::BigInt(const char& ch)
// {
// if(ch >='0' && ch<='9')
// {
// intgr = std::string(1, ch);
// dec = "0";
// sign = 1;
// }
// else
// {
// intgr = dec = "NaN";
// sign = 0;
// }
// }
BigInt::~BigInt()
{
//dtor
}
BigInt::BigInt(const BigInt& other)
{
//copy ctor
}
BigInt& BigInt::operator=(const BigInt& rhs)
{
if (this == &rhs) return *this; // handle self assignment
//assignment operator
this->intgr = rhs.intgr;
this->dec = rhs.dec;
this->sign = rhs.sign;
return *this;
}
std::ostream& operator<<(std::ostream& os, const BigInt& bigInt)
{
std::string num_str = "";
if (bigInt.sign == 0)
{
os << "NaN";
return os;
}
else if (bigInt.sign == -1)
num_str = "-";
num_str += bigInt.intgr;
if (bigInt.dec != "0")
{
num_str += ".";
num_str += bigInt.dec;
}
os << num_str;
return os;
}
std::istream& operator>>(std::istream& is, BigInt& bigInt)
{
std::string input_num;
is >> input_num;
bigInt = BigInt(input_num);
return is;
}
}// namespace GG ends here
int main()
{
using namespace std::string_literals;
char arr[] = "_-____20__999_______343_453_100_000_00____";
short short_n = 123;
GG::BigInt n(short_n);
GG::BigInt n_default;
GG::BigInt str_n('1');
GG::BigInt strstr("123"s);
GG::BigInt char_arr_n(arr);
std::cout << n << " " << n_default << " " << str_n << " " << char_arr_n << std::endl;
GG::BigInt input;
std::cout << "Input a number: ";
std::cin >> input;
std::cout << input;
return 0;
}
When run, displays
Code:
string constructor called.
matched.
string constructor called.
matched.
string constructor called.
matched.
char * constructor called
123 NaN 1 NaN
Input a number:
as I defined DEBUG_SYMS
PS There's no need to attribute me in the code.
Ohk so there is some problem with GCC I suppose. I have updated it to latest version but still, it is not compiling.
About your name, actually I forgot to delete it while sharing the files here, I deleted everything in the code I pasted directly into question but I forgot to prepare different files to upload and just uploaded the original ones on which I am working.
Sorry, but I use only VS. Can any guru who does use GCC advise?
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
you cannot specialize a member template inside class body ( VS allows but it's not standard ).
Regarding your original problem, it's better to use overloading instead, somthing like:
Code:
class BigInt
{
public:
BigInt();
explicit BigInt( char );
explicit BigInt( const char* );
explicit BigInt( std::string const& );
template<int N>
explicit BigInt(char (&arr)[N]); // this will take string literals BigInt("123")
template<typename T>
explicit BigInt( T const& );
....
you cannot specialize a member template inside class body ( VS allows but it's not standard ).
then it should be!
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
you cannot specialize a member template inside class body ( VS allows but it's not standard ).
Regarding your original problem, it's better to use overloading instead, somthing like:
Code:
class BigInt
{
public:
BigInt();
explicit BigInt( char );
explicit BigInt( const char* );
explicit BigInt( std::string const& );
template<int N>
explicit BigInt(char (&arr)[N]); // this will take string literals BigInt("123")
template<typename T>
explicit BigInt( T const& );
....
Thank you very much for the clarification.
But after making everything explicit I will not be able to do things like,
Code:
BigInt a = 1;
or
Code:
std::string str = "123";
BigInt a = str;
So, I guess it is better to specify that you can not use an array to initialize its object, instead of losing so much convenience.
So, I guess it is better to specify that you can not use an array to initialize its object, instead of losing so much convenience.
you don't need "explicit" for the array constructor, I added it just for correctness sake. Note that the more implicit converting constructors you add the higher the chances of getting unwanted/unexpected results. This is even more true when mixing converting constructors taking primitive types ( chars, ints, ... ) because you have to deal with the language implicit conversion/promotion rules ...
so, in real world big int libraries, implicit conversions are minimized in favour of explicit constructors and factory functions.
Moreover, you typically don't want unconstrained template constructors ( eg. BigInt( T const& ) ), these should be constrained via SFINAE to avoid troubles like the one you got in and to allow some extendability ...
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.