0

RTTI をケースセレクターとして使用するためのコードがあります

#include <iostream>
#include <vector>
#include <typeinfo>
#include <complex>
#include <algorithm>

using namespace std;

typedef complex<int> data;
typedef std::vector< data > List;

template <typename T> void zeros(T &v)
{
  if (typeid(typename T::value_type)==typeid(complex<int>))
    std::fill(v.begin(), v.end(), complex<int>(0, 0));
  else std::fill(v.begin(), v.end(), static_cast<typename T::value_type>(0));
}

int main(int argc, char *argv[])
{
  List A;

  zeros(A);
  return 0;
}

上記のコードでは、typename T::value_type を使用してリストのデータ型を決定します。複素数がある場合は、リストを複素数ゼロで埋めます。それ以外の場合は、対応する型のゼロにします。上記のコードで、データを int に設定すると、問題なくコンパイルおよび実行されます。しかし、別の別のタイプを設定すると、コンパイルに失敗します。上記のコードをさまざまなタイプのデータ (float、double、long、int、complex、complex、complex) で機能させる方法があるかどうか疑問に思います。

ps 何らかの理由で独自の複素数を作成する予定であり、複素数ゼロまたは実数ゼロを作成する方法をコードに指示する必要があるため、2 つのケースでベクトルを埋めたい理由。しかし、テストのために、組み込みのデータ型で動作させることさえできません

4

1 に答える 1

4

デフォルトで初期化された複合体 (0, 0) とゼロで初期化された int の両方が必要なようです。これは、値の初期化を使用して実現できます。

template <typename T> void zeros(T &v)
{
    std::fill(v.begin(), v.end(), typename T::value_type{});
}

に応じて分岐を実行したい場合はT::value_type、次のような型特性を使用することをお勧めします。

template<typename T>
struct default_value {
    static const T value;
};

template<>
struct default_value<std::complex<int>> { // assuming you'll use other complex type
    static const std::complex<int> value;
};

template<typename T>
const T default_value<T>::value = T{};
const std::complex<int> default_value<std::complex<int>>::value = std::complex<int>(0, 0);

// now use it
template <typename T> void zeros(T &v)
{
    std::fill(v.begin(), v.end(), default_value<typename T::value_type>::value);
}

ただし、組み込み型のデフォルトの構築と値の初期化で十分です。

于 2013-08-24T01:22:02.590 に答える