Graznarak
Graznarak

Reputation: 3740

static_assert referencing enclosing template class

In the following code, VS2015 complains at IsInstantiation<OtherType, T1>::value, giving this error "invalid template argument for template parameter 'TT', expected a class template". How would I go about fixing this? I would like to restrict OtherType to cases where T1 is wither SomeType or OtherType.

template <template<typename...> class TT, typename T>
struct IsInstantiation : std::false_type
{
};

template <template<typename...> class TT, typename... Ts>
struct IsInstantiation<TT, TT<Ts...>> : std::true_type
{
};

template <typename T1>
class SomeType{};

template <typename T1, typename T2>
class OtherType
{
    static_assert(IsInstantiation<SomeType, T1>::value ||
        IsInstantiation<OtherType, T1>::value,
        "Event must have SomeType or OtherType as first type");
public:
    explicit OtherType(T1 t1, T2 t2)
        : mT1{ std::move(t1) }
        , mT2{ std::move(t2) }
    {
    }

private:
    T1 mT1;
    T2 mT2;
};

Upvotes: 2

Views: 85

Answers (1)

max66
max66

Reputation: 66230

Try with

template <typename, typename>
class OtherType;

template <typename T1, typename T2>
using OtherTypeAlias = OtherType<T1, T2>;

template <typename T1, typename T2>
class OtherType
{
    static_assert(IsInstantiation<SomeType, T1>::value ||
        IsInstantiation<OtherTypeAlias, T1>::value,
        "Event must have SomeType or OtherType as first type");

The problem: inside OtherType, when you write OtherType, it is defaulted to OtherType<T1, T2>; so when you pass OtherType as argument of IsIstantiation, you pass a template type, not a template template.

-- EDIT --

I didn't know but is possible to cite directly the dry (without template default parameter) inside OtherType (thanks Barry!).

So is a lot simpler

O don't know how to cite directly the class OtherType -- as template-template, without the default templates arguments -- inside the body of OtherType

template <typename T1, typename T2>
class OtherType
{
    static_assert(IsInstantiation<SomeType, T1>::value ||
        IsInstantiation<::OtherType, T1>::value,
        "Event must have SomeType or OtherType as first type");

without alias

Upvotes: 2

Related Questions