5

vector現在、aを a に変換する次のような関数テンプレートがありますstring(要素をカンマで区切って、自然な文字列にします)。

//the type T must be passable into std::to_string
template<typename T>
std::string vec_to_str(const std::vector<T> &vec);

ご覧のとおり、これは組み込みstd::to_string関数 ( intdoubleなど)に要素を渡すことができるベクトルのみを対象としています。

許可されているコメントを文書化することは良い習慣と考えられていTますか? そうでない場合は、どうすればよいですか?これをより良い方法で実施することは可能ですか?

4

3 に答える 3

4

およびいくつかの式 SFINAE を使用static_assertすると、適切なコンパイル時のエラー メッセージを表示できます。

template<typename T>
constexpr auto allowed(int) -> decltype(std::to_string(std::declval<T>()), bool())
{
    return true;
}

template<typename>
constexpr bool allowed(...)
{
    return false;
}

template<typename T>
std::string vec_to_str(const std::vector<T>& vec)
{
    static_assert(allowed<T>(0), "Invalid value type.");
    return "";
}

struct foo {};

int main()
{
    std::vector<int> v_int;
    vec_to_str(v_int);

    std::vector<foo> v_double;
    vec_to_str(v_double);       // static_assert fires here
}
于 2012-12-14T22:55:18.670 に答える
2

は C++11 の機能であるためstd::to_string、C++11 ソリューションを受け入れる可能性があると思います。この特定のケースでは、末尾の戻り値の型を sfinae の方法で使用できます。

template <typename T>
auto vec_to_str(const std::vector<T>& vec) -> decltype(std::to_string(std::declval<T>()));

value-type が で機能しない場合、これは代用に失敗します (そしてそのオーバーロードを排除します) to_string。しかし、それでも、それは必ずしも規則を文書化して実施するための最も目を楽しませる方法ではありません。上記の Sfinae トリックの C++11 より前のバージョンもおそらく存在しますが、これほど優れたものはありません。

一般に、コメントでそれを文書化するだけでよいと思います (おそらく のような doxygen タグを使用します\tparam)。必要に応じて、Boost.Concept-Check のスタイルでコンセプト チェック メカニズムを使用できます。

std::ostream operator <<補足として、この特定のケースでは、関数ではなく を使用することをお勧めします。to_stringこれは、カスタム型 (たとえば、2D ベクトルなど) に出力用のオーバーロードが装備されている可能性が高いためです。ストリーム。

于 2012-12-14T22:52:25.877 に答える
0

概念が到着するまでdecltypeは、匿名型パラメーターを使用できます。

template<typename T,
  typename = decltype(std::to_string(std::declval<T>()))>
std::string vec_to_str(const std::vector<T> &vec);
于 2012-12-14T22:46:35.670 に答える