14

ハロー!

2 つのテンプレート タイプのうちの 1 つだけに特化したいと考えています。たとえばtemplate <typename A, typename B> class X、単一の関数に対して特別な実装が必要X<float, sometype>::someFunc()です。

サンプルコード:

main.h:

#include <iostream>

template <typename F, typename I>
class B
{
public:
    void someFunc()
    {
        std::cout << "normal" << std::endl;
    };

    void someFuncNotSpecial()
    {
        std::cout << "normal" << std::endl;
    };
};

template <typename I>
void B<float, I>::someFunc();

main.cpp:

#include <iostream>
#include "main.h"

using namespace std;

template <typename I>
void B<float, I>::someFunc()
{
    cout << "special" << endl;
}

int main(int argc, char *argv[])
{
    B<int, int> b1;
    b1.someFunc();
    b1.someFuncNotSpecial();

    B<float, int> b2;
    b2.someFunc();
    b2.someFuncNotSpecial();
}

のコンパイルに失敗しましたclass B。このように C++ でこれができないというのは本当ですか? 最善の回避策は何ですか?

[編集]

template <float, typename I> void B<float, I>::someFunc();main.h:26: エラー: 'float' はテンプレート定数パラメーターの有効な型ではありません

template <typename I> void B<float, I>::someFunc();main.h:27: エラー: 不完全な型「クラス B」の無効な使用</p>

そして、私はgccを使用しています。

[編集]

特殊化されていない関数が他にもあるため、クラス全体を特殊化したくありません。

4

4 に答える 4

22

クラス テンプレートの部分的な特殊化を提供する必要がありますB

template <typename I>
class B<float, I>
{
public:
    void someFunc();
};

template <typename I>
void B<float, I>::someFunc()
{
    ...
}

someFunc専門化内で定義することもできます。

ただし、クラスではなく関数のみを特殊化したい場合は、たとえば、

template <typename F, typename I>
void someFunc(F f, I i) { someFuncImpl::act(f, i); }

template <typename F, typename I>
struct someFuncImpl { static void act(F f, I i) { ... } };

// Partial specialization
template <typename I>
struct someFuncImpl<float, I> { static void act(float f, I i) { ... } };

しかし、このトリックなしでは関数テンプレートを特殊化することはできません。

于 2010-09-22T11:51:06.623 に答える
6

クラス テンプレートのメンバー関数を完全に特殊化することはでき ますが、_partially メンバー関数を特殊化することはできません。- アンドレイ・アレクサンドレスク

部分クラスの専門化は、他のポスターによって説明されています。

ただし、オーバーロードを使用できます。

template <class T, class U> T fun(U obj); // primary template
template <class U> void Fun<void, U>(U obj); // illegal pertial
// specialization
template <class T> T fun (Window obj); // legal (overloading)

これについて詳しく知りたい場合は、A. Alexandrescu による「Modern C++ Design」でこの問題について詳しく読むことができます。

于 2010-09-22T12:09:14.680 に答える