3

テンプレートを使用して、テンプレートで使用される特定のクラスに特定のメンバー変数があると想定できることを知っています。ただし、テンプレートクラスに特定のメンバー変数または関数が必要であることを明示的に宣言する方法があるかどうか疑問に思いました。

私はこの例のようなものについて話している:

template <typename T>
class Assume
{
    int value;
    Assume(T* object) : value(T->AssumedMember) {};
};


class A
{
    int AssumedMember;
    A(int val) : AssumedMember(val) {};
};


int main()
{
    A* a = new A(5);
    Assume<A> assumer(a);
    return 0;
}

少なくともMSVC++で使用されているコンパイラでは、この例に似たものが問題なくコンパイルされるはずです。

テンプレートまたはクラスで使用するために、タイプ名TのTにメンバー変数AssumedMemberがあることを宣言する方法があるかどうか疑問に思っていました。今のところ、Assumeが適切な必須メンバー(変数、関数、または演算子)を持つクラスで使用された場合にのみ機能することを実際に理解する唯一の方法は、コンパイルして指定されたコンパイラエラーを確認する必要があります。テンプレート全体を自分で読んで、まだ定義されていない余分なものが使用されているかどうかを判断してください。

(また、無関係なことに、宣言のブロック全体をテンプレートとして宣言する方法を知っている人はいます template <typename T> { /*class... member definitions, etc..*/ } か?同じテンプレートを使用するために定義のブロック全体を宣言するようなものを使用するかのように?)

4

2 に答える 2

2

標準委員会は、「コンセプト」と呼ばれるこの機能に取り組んできました。ただし、C++11にはなりませんでした。

ただし、(さまざまな機能を備えた)動作するコンパイラは2つあります。ConceptGCCまたはConceptClangを見てください。

于 2012-06-09T19:43:45.733 に答える
1

いいえ、テンプレートの定義以外にテンプレート要件を宣言する方法はありません。たとえば、static_assertsを使用して、これらの要件を定義の最前線に置き、より適切なエラーメッセージを表示できます。

複数のテンプレート関数を一度に宣言するには、静的メンバー関数でテンプレートクラスを使用できます。

template<typename T>
struct Foo {
    static int bar(T t);
    static T baz();
};

Foo<int>::bar(1);
auto s = Foo<std::string>::baz();

しかし、どのような種類のテンプレート宣言に対してもこれを行うための汎用的な方法はありません。これにより、多くのことを節約できるとは思いません。


static_assertsで使用するカスタムタイプの特性の例

私はいくつかのC++11のものを使用していますが、C++98でも実行できます

#include <type_traits>

// the custom type traits
template<typename T> struct exists : std::true_type {};

template<typename T>
struct has_value_type {
    template<typename U>
    static typename std::enable_if<exists<typename U::value_type>::value,char>::type
    Test(int);

    template<typename U> static int Test(...);
    static constexpr bool value = sizeof(Test<T>(0)) == sizeof(char);
};

template<typename T>
struct has_member_i {
    template<typename U>
    static typename std::enable_if<0!=sizeof(&U::i),char>::type Test(int);
    template<typename U> static int Test(...);
    static constexpr bool value = sizeof(Test<T>(0)) == sizeof(char);
};

// your template for which you want to declare requirements
template<typename T>
void test(T t) {
    static_assert(has_value_type<T>::value, "value_type must be a member type alias of T");
    static_assert(has_member_i<T>::value, "i must be a member variable of T");
}

// one type that meets the requirements and one that doesn't
struct Foo {
    typedef int value_type;
    int i;
};

struct Bar {};

int main() {
    test(Foo());
    test(Bar());
}
于 2012-06-09T19:40:16.347 に答える