4

現在、一連の型を取るクラス テンプレートがあります。各タイプは、クラス自体でインスタンス化する必要がある場合があります。私が現在持っているものは次のようなものです:

template <typename... Types>
struct TypeList; // Not defined

struct Placeholder; // Not defined

template <typename Types, typename AnotherType = Default>
class MyClass
{
    // ...
};

その後、次のように使用できます。

typedef MyClass<TypeList<Container1<Placeholder>, Container2<std::string,
        Placeholder>, OtherType>, OptionalType> MyTypedef;
MyTypedef my_object;

MyClassの外観Placeholderをそれ自体に置き換え、結果の型を使用します。すべて問題ありません。

次のいずれかのようなことをしようとすると、問題が発生します。

MyTypedef *my_ptr = &my_object;
my_free_function(my_object);

Container1<Placeholder>コンパイラがインスタンス化Container2<std::string, Placeholder>して引数依存ルックアップ (ADL) を実行しようとするため、これらは両方ともコンパイラ エラーを引き起こします。このインスタンス化Placeholder自体は失敗します。

たとえば、次のようにすることで ADL を回避できることを知っています。

MyTypedef *my_ptr = std::addressof(my_object);
(my_free_function)(my_object);

MyClassただし、常に ADL を抑制しなければならないことで、ユーザーに負担をかけたくありません。ADL に型を使用せずに、ユーザーに型のリストを提供させる別の簡単な方法はありますか?

4

1 に答える 1

0

わかりました、すべてが機能しました。秘訣は、テンプレートを直接使用する代わりに依存型を使用することでした。私の最終的な解決策は、次のように TypeList を定義することでした。

template <typename... Types>
struct TypeList
{
private:
    struct Holder
    {
    private:
        typedef TypeList<Types...> InnerTypeList;
        template <typename Types, typename AnotherType>
        friend class MyClass;
    };
public:
    typedef Holder type;
};

次に、MyClass のユーザーができること

typedef MyClass<TypeList<Container1<Placeholder>, Container2<std::string,
        Placeholder>::type, OtherType>, OptionalType> MyTypedef;
MyTypedef my_object;

「::type」の追加に注意してください

最後に、MyClassで、私は置き換えました

typedef typename SubstituteType<Types, Placeholder, MyClass>::type InternalTypeList;

typedef typename SubstituteType<Types::InnerTypeList, Placeholder, MyClass>::type
        InternalTypeList;

InternalTypeList以前と同じタイプを私に与えてください。

依存型Holderには独自のテンプレート パラメーターがないため、コンパイラは ADL の目的でプレースホルダー型をインスタンス化する必要がなく、すべてが適切に機能します。

于 2013-02-11T19:02:23.640 に答える