4

C++ テンプレートの難問に遭遇しました。私はそれを最小限に抑えようとしましたが、今私がやろうとしていることが可能かどうかさえわかりません. 次のコード (一部の .h ファイル内) を見てください。

template<typename T>
class A
{
public:
    template<typename S>
    void f(S x);
};

class B1 { };

template<typename S>
class B2 { };

//This one works:
template<>
template<typename S>
void A<B1>::f(S x)
{
}    

//This one does not work:
template<>
template<typename S>
void A<B2<S>>::f(S x)
{
}

私のmain機能では、次のようなものがあります。

//This one works:
A<B1> first;
first.f<int>(5);

//This one does not work:
A<B2<int>> second;
second.f<int>(5);

2番目の部分が原因で表示されるエラーメッセージは

error C3860: template argument list following class
             template name must list parameters in the
             order used in template parameter list

error C3855: 'A<T>': template parameter 'T' is
             incompatible with the declaration

問題は何ですか?


編集

問題をより具体的にするために、ここに私の動機があります。上記の関数に、、およびのf特殊化を持たせたいのですが、 の型はまだバインドされていません。T=std::tuple<T1, T2>T=std::tuple<T1, T2, T3>T=std::tuple<T1, T2, T3, T4>tuple

4

3 に答える 3

4

コードには 2 つの問題があります。まず、2 番目の専門化は違法です。

template<> // parameters useable for the specialization of A you refer to
           // since it is a function, no partial specialization is allowed.
template<typename S> // parameters for the function's parameters
void A<B2<S>>          // S can not be used here!
             ::f(S x)  // only here
{
}

それを変更すると

template<>
template<typename S>
void A<B2<int>>::f(S x)
{
}

それは機能し、2 番目の問題が明らかになりました。

second.f<B2<int>>(5);

これは に設定SされB2<int>、関数はパラメーターを期待しますS xが、整数5はその型に変換できません。次のように変更します。

B2<int> x;
second.f<B2<int>>(x);

そしてそれも同様に機能します。

これは、解決しようとしていた問題を解決しない可能性があることに注意してください。何が起こるかを説明しているだけです。


あなたの編集について考えてみてください: あなたが専門化しようとしているという事実は、T=std::tuple<...>すでに方向性を示していると思います:Tのテンプレート パラメータでAあり、それがあなたが専門化すべきものです。たぶん次のようなもの:

template< typename T >
class F // used to implement f(), so you can specialize
        // just F/f() instead of the whole class A
{
  void f(T x) { /* default impl */ }
};

template< typename T1, typename T2 >
class F< std::tuple< T1, T2 > >
{
  void f(T1 x, T2 y) { /* special impl */ }
};

template< typename T >
class A : public F< T >
{
    // ...other stuff...
};
于 2013-03-08T20:07:31.680 に答える
4

メンバー関数テンプレートを部分的に特殊化しようとしています。それは不可能です、恐れ入ります...

于 2013-03-08T19:50:29.370 に答える
1

If you want to pass another template to a template, you have to use template template parameters, so your A<> template would look like this:

template<typename T>
class A
{
public:
    template<template <typename> class H, typename S>
    void f(H<S> x);
};

Now you can pass a template to your template.

I don't think you can specialize on template template parameters if your original template didn't take such an parameter type.

于 2013-03-08T19:46:29.527 に答える