我有一個簡單的結構,它繼承自std::ostringstream,以便更好地處理資料庫的一些值。如果我只是繼承并添加一個簡單的建構式來設定雙精度的寬度,它就可以正常作業。
struct myostream : std::ostringstream {
myostream() noexcept( false ) {
this->precision( 6 );
this->setf( ios_base::fixed, ios_base::floatfield );
}
};
現在,我正在嘗試添加一個operator<<for type double,以處理無窮大和 NaN。
myostream &operator<<( double val ) {
if ( std::isnan( val ) ) {
*static_cast<std::ostringstream *>( this ) << "'NaN'";
} else if ( std::isinf( val ) ) {
*static_cast<std::ostringstream *>( this ) << ( val < 0 ? "'-Infinity'" : "'Infinity'" );
} else {
*static_cast<std::ostringstream *>( this ) << val;
}
return *this;
}
當我在添加此功能,我只是得到模棱兩可的函式呼叫無處不在,每一個型別(bool,char,char *,int,等)。
2>...\include\myostream.hpp(13,14): message : could be 'myostream &myostream::operator <<(double)' (compiling source file ...)
2>C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.30.30704\include\ostream(694,32): message : or 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,char)' (compiling source file ...)
2>C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.30.30704\include\ostream(775,31): message : or 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,char)' (compiling source file ...)
2>C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.30.30704\include\ostream(856,32): message : or 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,_Elem)'
2> with
2> [
2> _Elem=char
2> ] (compiling source file ...)
2>C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.30.30704\include\ostream(898,31): message : or 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,signed char)' (compiling source file ...)
2>C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.30.30704\include\ostream(909,31): message : or 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,unsigned char)' (compiling source file ...)
2>C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.30.30704\include\thread(275,26): message : or 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,std::thread::id)' (compiling source file ...)
2>...: message : or 'built-in C operator<<(int, int)'
2>...: message : while trying to match the argument list '(myostream, char)'
所以,我的問題是:如何operator<<在不增加歧義的情況下覆寫某些型別?這甚至是可能的,還是我需要創建一個回傳字串的函式?
編輯:添加using std::ostringstream::operator<<;只會增加歧義的數量。
uj5u.com熱心網友回復:
這是一種選擇:
struct myostream : std::ostringstream {
using std::ostringstream::operator<<; // bring in all the member overloads
myostream() noexcept( false ) {
this->precision( 6 );
this->setf( ios_base::fixed, ios_base::floatfield );
}
// call the base class member function explicitly in here:
myostream &operator<<( double val ) {
if ( std::isnan( val ) ) {
std::ostringstream::operator<<("'NaN'");
} else if ( std::isinf( val ) ) {
std::ostringstream::operator<<( val < 0 ? "'-Infinity'" : "'Infinity'" );
} else {
std::ostringstream::operator<<(val);
}
return *this;
}
};
// front-end for all the free operator<< functions:
// (this could be narrowed down to not match on T:s that isn't supported)
template<class T>
myostream& operator<<(myostream& m, const T& x) {
static_cast<std::ostringstream&>(m) << x;
return m;
}
uj5u.com熱心網友回復:
當 of 的型別T不是double諸如 時char,會隱式轉換為doubleand call myostream::operator<<,但由于ostream::operator<<有char多載,myostream也會隱式轉換為ostream并呼叫 base 的operator<<,所以這里有歧義。
您可以使用 SFINAE 來防止doublein myostream::operator<<when Tis not a的隱式轉換double:
template<class T>
inline std::enable_if_t<std::is_same_v<T, double>, myostream&>
operator<<(myostream& os, T val ) {
if ( std::isnan( val ) ) {
static_cast<std::ostringstream &>( os ) << "'NaN'";
} else if ( std::isinf( val ) ) {
static_cast<std::ostringstream &>( os ) << ( val < 0 ? "'-Infinity'" : "'Infinity'" );
} else {
static_cast<std::ostringstream &>( os ) << val;
}
return os;
}
演示。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/328477.html
標籤:C
