0

タイプの要素を次のような出力ストリームに追加できるstd::vector<T>限り、すべての文字列表現を与える C++ 関数を実装することは可能ですか?T

T x;
...
std::cout << x << std::endl;

文字列表現は次のようになります

[x, y, z]

私は次のことを試みましたが、どうすれば?よいですか?

template <typename T> std::string vectorToString(std::vector<T>& vec) {
    std::string s;
    for (T element : vec) {
        ?
    }
    return s;
}
4

5 に答える 5

3

stringstream書式設定を行うには、次のようにします。

std::ostringstream ss;
ss << '['
bool first = true;
for (T const & element : vec) {
    if (!first) {
        ss << ", ";
    }
    ss << element;
    first = false;
}
ss << ']';
return ss.str();
于 2013-01-11T13:56:58.110 に答える
1

std::ostringstreamインスタンスを使用して?を返しstd::ostringstream::str()ます。

std::ostringstream s;
s << "[";

for (auto i(vec.begin()); i != vec.end(); i++)
{
    if (vec.begin() != i) s << ", ";
    s << *i;
}
s << "]";

return s.str();
于 2013-01-11T13:55:30.710 に答える
1

C++11 を使用している場合は、次の単純なバージョンを使用できます。

#include <sstream>
#include <algorithm>

using namespace std;

template<typename T>
string format(vector<T> const& v)
{
    if (v.empty()) return "[]";
    ostringstream ss;
    ss << "[" << v[0];
    for_each(begin(v) + 1, end(v), [&ss] (T const& s) { ss << ", " << s; });
    ss << "]";
    return ss.str();
}

他のタイプのコレクション( だけでなくvector) またはコレクションのサブ範囲に対してもジェネリックにしたい場合は、次のように一般化できます。

#include <sstream>
#include <algorithm>

using namespace std;

template<typename It>
string format(It b, It e)
{
    if (b == e) return "[]";
    ostringstream ss;
    ss << "[" << *b;
    for_each(++b, e, [&ss] (decltype(*b)& s) { ss << ", " << s; });
    ss << "]";
    return ss.str();
}

template<typename C>
string format(C const& c)
{
    return format(begin(c), end(c));
}

int main()
{
    vector<int> v = { 4, 5, 5, 8 };
    cout << format(v) << endl;
    return 0;
}
于 2013-01-11T14:18:12.370 に答える
0

少し速いバージョン

template <typename T> std::string vectorToString( const std::vector<T>& vec ) {
    if ( vec.empty() ) {
        return "[]";
    }
    std::ostringstream s;
    s << "[" << vec.front();

    for (auto i = vec.begin() + 1, e = vec.end(); i != e; i++)
    {
        s << ", " << *i;
    }
    s << "]";

    return s.str();
}

,別の瞬間:ベクトル内の文字列が開始または終了する場合、印刷された文字列の数を理解するのは難しいため、この関数を文字列に特化して引用符で囲むのが正しいかもしれません。

template <>
std::string vectorToString< std::string >( const std::vector<std::string>& vec ) {
    if ( vec.empty() ) {
        return "[]";
    }
    std::ostringstream s;
    s << "[" << vec.front();

    for (auto i = vec.begin() + 1, e = vec.end(); i != e; i++)
    {
        s << ", \"" << *i << "\"";
    }
    s << "]";

    return s.str();
}
于 2013-01-11T14:07:38.027 に答える
0

通常はコードを簡素化するアルゴリズムを使用します (この場合はわかりませんが、完成のために追加されています)。

template <typename T>
std::string toString( std::vector<T> const & v ) {
   if (v.empty()) 
      return "[]";
   typename std::vector<T>::const_iterator last = std::prev(v.end());
   std::ostringstream st;
   st << "[ ";
   std::copy( v.begin(), last, std::ostream_iterator<T>(st,", ") );
   st << *last << " ]";
   return st.str();
}
于 2013-01-11T14:33:26.040 に答える