C++関数のリロード時に戻り値のタイプにもリロード決議を加えるにはどうすればいいですか?
周知のように、C++関数のリロード時の戻り値は、リロード決定に関与しません.つまり、
int lex_cast(const char*);
double lex_cast(const char*);
このような2つの関数が同じコンパイルユニットの同じnamespaceにある場合、コンパイルエラーが発生する.
どうしようかな?
小さなテクニック:
ほとんど言うに値しないほど小さい.しかし、このコードでは、注意深い人が疑問を提起するかもしれません.
ここで返されるconst char*は一時変数に属し、my_キャストはこの一時変数をメンバーに保存したが、ここで成功したのは間違いない.解放されたc_のためだ.str()そのメモリはちょうど再割り当てされていないので、危険です.
実際には、これは問題ありません.C++の標準は、一時変数の生存期間は、真のサブ式ではなく、その式(全体)を含むことを規定しています.この言葉をよく味わいましょう.
上はただmy_cast非テンプレートの場合my_castにはテンプレートパラメータが含まれ、my_キャストメンバーもテンプレートでなければなりませんが、どうすればいいですか?
補助テンプレートクラスを定義し、テンプレート関数を追加してテンプレートクラスをインスタンス化するだけです.
核心思想はただ一つ:operator class conversionを使って、以下は比較的に実用的なcastで、boost::lexical_を使っていませんキャスト、亀速をコンパイルする問題はありません.(boostはtemplateを使いすぎた)
int lex_cast(const char*);
double lex_cast(const char*);
このような2つの関数が同じコンパイルユニットの同じnamespaceにある場合、コンパイルエラーが発生する.
どうしようかな?
小さなテクニック:
#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
class my_cast {
const char* s;
public:
template<class Target>
operator Target() const {
return boost::lexical_cast<Target>(s);
}
my_cast(const char* s) : s(s) {}
};
int main() {
using namespace std;
long long ll = my_cast("12345678910111213");
int ii = my_cast("-123");
string ss = my_cast("abcde");
double dd = my_cast(('3' + string(".2222")).c_str());
cout << ll << endl;
cout << ii << endl;
cout << ss << endl;
cout << dd << endl;
return 0;
}
ほとんど言うに値しないほど小さい.しかし、このコードでは、注意深い人が疑問を提起するかもしれません.
('3' + string(".2222")).c_str()
ここで返されるconst char*は一時変数に属し、my_キャストはこの一時変数をメンバーに保存したが、ここで成功したのは間違いない.解放されたc_のためだ.str()そのメモリはちょうど再割り当てされていないので、危険です.
実際には、これは問題ありません.C++の標準は、一時変数の生存期間は、真のサブ式ではなく、その式(全体)を含むことを規定しています.この言葉をよく味わいましょう.
上はただmy_cast非テンプレートの場合my_castにはテンプレートパラメータが含まれ、my_キャストメンバーもテンプレートでなければなりませんが、どうすればいいですか?
template<class Source>
class my_cast_imp {
Source s;
public:
template<class Target>
operator Target() const {
return boost::lexical_cast<Target>(s);
}
my_cast_imp(const Source& s) : s(s) {}
};
template<class Source>
my_cast_imp<Source> my_cast2(const Source& s) {
return my_cast_imp<Source>(s);
}
補助テンプレートクラスを定義し、テンプレート関数を追加してテンプレートクラスをインスタンス化するだけです.
核心思想はただ一つ:operator class conversionを使って、以下は比較的に実用的なcastで、boost::lexical_を使っていませんキャスト、亀速をコンパイルする問題はありません.(boostはtemplateを使いすぎた)
#include <stdlib.h>
#include <string>
class goldcast_imp {
const char* s;
int base;
public:
goldcast_imp(const char* s, int base)
: s(s), base(base)
{}
operator int () const { return (int) strtol (s, NULL, base); }
operator unsigned() const { return (unsigned)strtoul(s, NULL, base); }
operator signed long () const { return strtol (s, NULL, base); }
operator signed long long() const { return strtoll (s, NULL, base); }
operator unsigned long () const { return strtoul (s, NULL, base); }
operator unsigned long long() const { return strtoull(s, NULL, base); }
operator float() const { return strtof(s, NULL); }
operator double() const { return strtod(s, NULL); }
operator long double() const { return strtold(s, NULL); }
operator std::string() const { return std::string(s); }
};
goldcast_imp goldcast(const std::string& s, int base = 10) {
return goldcast_imp(s.c_str(), base);
}
goldcast_imp goldcast(const char* s, int base = 10) {
return goldcast_imp(s, base);
}