2

任意の型をタイプセーフにカプセル化できる型を作ろうとしています。私はこの答えからこれが可能かもしれないという考えを頭の中で思いつきました:5年後、「可能な限り最速のC ++デリゲート」よりも優れたものはありますか?これまでのところ、問題の解決に成功しただけですが、原因が見つからないというエラーが発生しました。

コンパイラは、値を値自体の型にキャストできないと言っているようです。これは奇妙なことです。

llvm-gcc 4.2(gcc 4.2.1フロントエンド)でMac OSX10.6を実行しています。

ボイド*を取り除く方法や、重要性の低い位置に移動する方法の提案は歓迎されますが、この質問は実際にはそれに関するものではありません。

エラー:

$ g++ main.cpp
main.cpp: In static member function ‘static Stamp StampFactory<T>::make(T*) [with T = int]’:
main.cpp:33:   instantiated from ‘Stamp makeStamp(T*) [with T = int]’
main.cpp:39:   instantiated from here
main.cpp:26: error: could not convert template argument ‘t’ to ‘int*’

コード:

typedef void (*VoidFunc)(void*);

struct Stamp
{
    Stamp(VoidFunc p)
    {
        this->press = p;
    }
    VoidFunc press;
};

template<typename T>
struct StampFactory
{
    template<T* rvalue>
    struct Pattern
    {
        void operator()(void* lvalue)
        {
            *dynamic_cast<T*>(lvalue) = *rvalue;
        }
    };

    static Stamp make(T* t)
    {
        return Stamp(Pattern<t>()); // 28
    }
};

template<typename T>
Stamp makeStamp(T* t)
{
    return StampFactory<T>::make(t); // 33
}

int main(int argc, char** argv)
{
    int i = 0;
    Stamp s = makeStamp(&i); //39
}
4

1 に答える 1

4

このエラーは、テンプレート引数がコンパイル時定数(またはconstexpr)である必要があるため、変数(または関数パラメーター)にすることができないためです。テンプレート引数としてポインタを持つことは許可されていますが、コンパイル時の定数ポインタ値である必要があるため、そこにフィードできるものは多くありません(そして、私が考えることができるのはcharだけです-文字列リテラルへのポインタ)。一般的なルールは単純です。型か値かに関係なく、すべてのテンプレート引数はコンパイル時に認識されている必要があります。これには、関数パラメーターまたは他の種類の実行時変数は含まれません。

あなたが望むことを達成するための代替案を提案できればいいのですが、あなたが実際に何をしようとしているのかまったく理解できません。

于 2012-09-14T15:29:25.270 に答える