1
using namespace std;
#include <vector>
#include <string>

template <class T>
struct ValNode {
    string id;
    T value;
};

class ValTable {
public:
    ValTable();
    template <class T>
    void add(string,T);
    const bool find(string);
    void remove(string);
private:
    template<class T>
    std::vector<ValNode<T>*> vals;
};

コンパイラ エラー:error: data member 'vals' cannot be a member template

構造体で T* 値を使用しようとしましたが、うまくいきませんでした。コード内の関数はまだ使用していません。それを* .oファイルにコンパイルしようとしていました(.cppファイルも)。

4

5 に答える 5

1

C++ では、クラスにテンプレート メソッドを含めることができますが、テンプレート データ メンバーを含めることはできません。例えば:

template<typename T, int n>
struct FixedVector {
    T x[n];
    FixedVector() {
        for (int i=0; i<n; i++) x[i] = 0;
    }

    template<typename C>
    void copy(const C& container) {
        if (container.size() != n) {
            throw std::runtime_error("Wrong size");
        }
        int j = 0;
        for (typename C::const_iterator i=container.begin(),
                                        e=container.end();
             i!=e;
             ++i)
        {
            x[j++] = *i;
        }
    }
};

上記のクラスを使用すると、ベクトルやリストなど、 と を持つものを宣言しFixedVector<int, 5> fて呼び出すことf.copy(v)ができます。テンプレートメソッドも同様です。つまり、コンパイラは、関数に渡す型ごとに異なるバージョンを生成します。vsize beginendFixedVector::copy

std::vector<double> y;
y.push_back(3.4); y.push_back(5.6); y.push_back(7.8);

std::list<unsigned char> z;
z.push_back('a'); z.push_back('b'); z.push_back('c');

FixedVector<int, 3> v;
v.copy(y);  // This is ok
v.copy(z);  // This is ok too

C++ はテンプレートデータ メンバーを許可しません。これは、特定のコンパイル ユニットで使用している型の数に応じて異なるクラス サイズを意味し、これは一度に 1 つのユニットの C++ コンパイル モデルと一致しないためです。 .

メソッドの追加は、クラスのサイズに影響しないため問題ありません。また、異なるコンパイル ユニットから同じメソッドの複数のコピーをプルすることを避けることで、リンク時にすべてを修正できます。

于 2013-09-19T17:12:07.297 に答える
0

テンプレート メンバー値を持つことはできません。各翻訳単位が異なるインスタンス化にアクセスする可能性があり、その結果、オブジェクト レイアウトが異なります。何らかの方法でタイプを除外する必要があります。

標準ライブラリは、目的の行に沿って何かを行います。std::localeそれぞれstd::localeが異なる型のオブジェクトのコレクションを格納します。それは社会的な目的であり、あなたの目的のために直接使用することはできません.

基本的な考え方は、使用される各型を に自動的にマップし、intそれを使用してその型をインスタンスにマップすることです。メンバーはvals、正しいインスタンスを検索する関数テンプレートになります。大まかなアウトラインは次のようになります。

int type_index_alloc() { 
    static std::atomic<int> current(0);
    return ++current;
}
template <typename T>
int type_map() {
    static int rc = type_index_alloc();
}
class container {
    struct base { virtual ~base() {} };
    template <typename T>
    struct value: base { T v; };
    std::map<int, std::shared_ptr<base>> vals_;
public:
    T& vals()  {
        std::shared_ptr<base>& rc(vals_[type_map<T>()]);
        if (!rc) {
            rc = std::make_shared<value<T>>()); }
        return static_cast<value<T>&>(*rc).v;
    }
};

これは、物事がどのようにセットアップされているかを示しようとしているだけです。現在、コンパイラにアクセスできません。また、コード例では型のオブジェクトへのアクセスを提供しているだけですが、代わりにTa を使用するように簡単に変更できますstd::vector<T>

于 2013-09-19T17:14:38.290 に答える
0

ValTableテンプレートとして宣言する必要があります

template <class T>
class ValTable{
public:
    ValTable();
    //template <class T>
    void add(string,T);
    const bool find(string);
    void remove(string);
private:
    //template<class T>
    std::vector<ValNode<T>*> vals;
};
于 2013-09-19T16:53:44.533 に答える
0

ValTableテンプレートである必要があることはできません

あなたはこれを持つことができます:

template <class T> //Make the class as template
class ValTable {
public:
    ValTable();
    template <class X>
    void add(string,X);
    const bool find(string);
    void remove(string);
private:
    //template<class T>
    std::vector<ValNode<T>*> vals;
};
于 2013-09-19T16:55:28.663 に答える