0

文字列をテンパテTに切り替えるtemplate<classT> T string_to_T(const string&s)関数を書きたい。Tはint / double / stringにすることができ、次のように書く。

template<class T> T Config::string_to_T(const string& s){
    T t;
    bool at_in = false;

    istringstream ist(s);
    ist >> t;

    return t;
}

ただし、文字列に空白がある場合は機能しません。たとえば、string = '1 2 3 4'の場合、返されるtは文字列型で4に等しくなります。ニーズに合わせて変更するにはどうすればよいですか?

4

3 に答える 3

3

を参照してくださいboost::lexical_cast>>基本的に、あなたはあなたが望むことをしない場合に特化する必要があります。string_to_T<std::string>たとえば、ノーオペレーションになりたい場合は 、スペシャライゼーションを作成します。

template<>
std::string
string_to_T<std::string>( std::string const& s )
{
    return s;
}

より複雑なケースでは、機能オブジェクトに転送して部分的な特殊化を使用できますが、説明するケースでは、これは必要ありません。

その間、おそらくエラー処理について考える必要があります。string_to_T<int>を呼び出し、入力が「abcd」の場合はどうなりますか?さらに言えば、で呼び出す string_to_T<int>"1 2 3 4"、結果は1になるのでしょうか、それともエラーになるのでしょうか。

編集:

質問に対するコメントをもっと見てきました。実行時に戻り値の型を変更することはできません(クラス階層内の参照またはポインターを返す場合の特定の非常に限られた例外を除きます)。C ++は静的に型付けされた言語であり、すべての式には、コンパイル時に決定される個別の型があります。2つの異なるタイプを返すことができると仮定すると、関数をどのように使用するか、およびコンパイラーが検出に必要なタイプエラーをどのように検出できるかを示します。最も近いのは、さまざまなタイプへの暗黙の変換を使用して、ある種のプロキシを返すことですが、変換先のタイプは、結果の処理に応じて静的に決定されます。これをに割り当てますintint文字列の内容に関係なく、に変換します。

このタイプの安全性は機能です。コンパイル時にエラーを検出すると、エラー検出を実行時に延期するよりもはるかに堅牢で確実なコードになります。この安全性なしで実行でき(重要ではないアプリケーション)、ランタイムタイピングの柔軟性を追加する必要がある場合、C++は適切な言語ではありません。Pythonのようなものを使用する必要があります。

編集2:

あなたのコメントに応えて、解決策は次のようなもののように思われます:

class ToStringHelper
{
    std::string myValue;
public:
    ToStringHelper( std::string const& value )
        : myValue( value )
    {
    }
    operator std::string() const
    {
        return myValue;
    }
    template <typename T>
    operator T() const
    {
        std::istringstream cvt( myValue );
        T results;
        cvt >> results;
        //  Error checking here...
        return results;
    }
};

ToStringHelper
string_to_T( std::string const& s )
{
    return ToStringHelper( s );
}

この正確なパターンを構成データに使用します(エラーが例外をトリガーします)。

于 2012-12-01T11:33:01.327 に答える
0

std::stringあなたが示した関数はからへの変換を行っていますTTコンパイル時に指定しますが、実行時に変更することはできません。

タイプを値に依存させたい場合は、バリアントを使用できます。たとえば、 Boost.Variantを参照してください(Qtを使用している場合は、QVariantがあります)。Boost.AnyVariantとAnyの違い)を使用することもできます。変換には、Boost.Lexical_Castを使用することをお勧めします。おそらく、それとバリアント/anyで"1" -> 1自分自身を指定する必要があります。"1 2 3 4" - > "1 2 3 4"これらすべての関数では、型を処理するためのコードを追加する必要があることに注意してください。バリアントを使用すると、訪問者を使用できます。これは、バリアントのさまざまなタイプを処理するための非常に強力な方法です。

于 2012-12-01T11:33:08.070 に答える
0

任意のデータ型を文字列に変換するコード:

#include <string>
#include <sstream>
#include <iostream>
using namespace std;


template <class T>
string toString(const T& t)
{
    std::stringstream ss;
    ss << t;
    return ss.str();
}


int main(void)
{


    string str;

    cout<<"Convert any datatype to string\n\n\n";

    int i=1234;
    str=toString(i );
    cout<<"int i= "<<str<<"\n";


  cout<<" \nPress any key to continue\n";
  cin.ignore();
  cin.get();

   return 0;
}
于 2012-12-01T11:44:59.907 に答える