2015-04-08 3 views
4

как я мог заставить static_assert в этом данном классе:Force static_assert стрелять во время типа инстанцирования

template < int I > 
struct foo 
{ 
    static_assert(I < 5 ,"I must be smaller than 5!"); 
}; 

огнь, когда я создаю экземпляр шаблона нет, когда я инстанцирование результирующего типа:

int main() 
{ 
    typedef foo<5> t; // compiles 
    t tt; // will not compile 
} 
+2

Вся причина 'typedef foo < 5 > t;' compiles - это потому, что он * не * создает экземпляр вашего шаблона. – hvd

ответ

4

Одно предложение

template <int I> 
struct foo_guard { 
    static_assert(I < 5, "I must be smaller than 5!"); 
    typedef void type; 
}; 
template < int I, typename = typename foo_guard<I>::type> 
struct foo 
{ 
}; 
+0

Благодарим вас и всех остальных за все хорошие решения. К сожалению, я могу указать только один ответ в качестве правильного ответа. –

+0

при реализации вашего решения, мне было удобно использовать третий шаблон в качестве интерфейса, чтобы скрыть параметр по умолчанию. –

4

Может быть, более элегантный способ, но вы можете сделать foo metafunction, который относится к себе:

template < int I > 
struct foo 
{ 
    static_assert(I < 5 ,"I must be smaller than 5!"); 
    typedef foo<I> type; 
}; 

int main() 
{ 
    typedef typename foo<5>::type t; // won't compile 
} 
3

Чтобы сохранить влияние на существующий код как можно ниже, вы можете использовать шаблон псевдоним:

template <int I> 
struct foo_impl 
{ 
    static_assert(I < 5 ,"I must be smaller than 5!"); 
}; 

template <int I, int = sizeof(foo_impl<I>)> 
using foo = foo_impl<I>; 

int main() 
{ 
    typedef foo<5> t; 
} 

Это позволяет статическое утверждение будет храниться с остальная часть реализации, но не требует кода, использующего foo<N>, для использования другого синтаксиса для обращения к шаблону.

1
template < int I, class=std::enable_if_t< (I<5) > > 
struct foo {}; 

live example.

Здесь мы делаем тест SFINAE, который ограничивает I.

+0

Это окончательное решение, которое я имею в виду для внутренних частей библиотеки. Но для части интерфейса мне нравятся подробные static_asserts. –

Смежные вопросы