static-assert

Why does the `static_assert` always get invoked?

人盡茶涼 提交于 2019-12-02 17:53:21
问题 If USE_STATIC_ASSERT is 0 , this works as expected (getting indexed type from the list). If 1 the static_assert() is always tripped. I would have thought that the static_assert() would only happen if all the typename s were exhausted. Why is this not so? #define USE_STATIC_ASSERT 1 template <unsigned int I, typename ...Ts> struct items; template <typename T, typename ...Ts> struct items<0, T, Ts...> { typedef T type; }; template <unsigned int I, typename T, typename ...Ts> struct items<I, T,

When to use `static_assert` instead of SFINAE?

情到浓时终转凉″ 提交于 2019-12-02 16:19:16
I have been using (and seen used) static_assert to flag undesired values of template parameter values. However, for all cases I came across it seems better and more elegant to disable those undesired values via SFINAE. For example template<typename T, class = std::enable_if<std::is_floating_point<T>::value>::type> struct Foo { ... }; instead of template<typename T> struct Foo { static_assert(std::is_floating_point<T>::value, "Foo<T>: T must be floating point :-("); ... }; So my question: when to use static_assert instead of SFINAE and why? EDIT I think what I've learned so far is the following

Why does the `static_assert` always get invoked?

匆匆过客 提交于 2019-12-02 07:55:11
If USE_STATIC_ASSERT is 0 , this works as expected (getting indexed type from the list). If 1 the static_assert() is always tripped. I would have thought that the static_assert() would only happen if all the typename s were exhausted. Why is this not so? #define USE_STATIC_ASSERT 1 template <unsigned int I, typename ...Ts> struct items; template <typename T, typename ...Ts> struct items<0, T, Ts...> { typedef T type; }; template <unsigned int I, typename T, typename ...Ts> struct items<I, T, Ts...> : items<I-1, Ts...> { }; #if USE_STATIC_ASSERT template <unsigned int I> struct items<I> {

C++11 static_assert (and functions to be used therein)

强颜欢笑 提交于 2019-12-02 05:24:54
static_assert seems to be a very nice feature together with templates. However, I have trouble finding functions in the standard library for doing various tests at compile time. For example, I am looking for a function to check whether a type is a subtype of another one. boost::is_base_of does the job, however, is a comparable function in std, so I do not need to rely on boost. Basically, is there a good source for a list of functions which can be used in static_assert and are contained in the standard library of C++11? When is static_assert executed? Can I put it anywhere in a template and it

Comparing constexpr function parameter in constexpr-if condition causes error

孤者浪人 提交于 2019-12-02 04:09:00
I'm trying to compare a function parameter inside a constexpr-if statement. Here is a simple example: constexpr bool test_int(const int i) { if constexpr(i == 5) { return true; } else { return false; } } However, when I compile this with GCC 7 with the following flags: g++-7 -std=c++1z test.cpp -o test I get the following error message: test.cpp: In function 'constexpr bool test_int(int)': test.cpp:3:21: error: 'i' is not a constant expression if constexpr(i == 5) { return true; } However, if I replace test_int with a different function: constexpr bool test_int_no_if(const int i) { return (i =

How to secure CRTP against providing wrong superclass? [duplicate]

╄→尐↘猪︶ㄣ 提交于 2019-12-02 02:29:08
问题 This question already has answers here : How to avoid errors while using CRTP? (5 answers) Closed 4 years ago . In the curiously recurring template pattern, we write template <class Derived> class Base { }; class Derived : public Base<Derived> { }; What would be a good way to make the code robust another copy-paste omissions, so that the following snippet throws a compile-time error: class AnotherDerived : public Base<Derived> { }; I'm using Visual C++ 2013. 回答1: Make Base 's destructor

How to restrict template parameter to pointer or random access iterator only?

匆匆过客 提交于 2019-12-01 20:48:21
Is there a way to restrict the parameter type of a template function to only pointers or random-access iterators? Say I am developing a sorting function which works only with random accessible containers. I am looking for a way to throw a compile-time error if the user passes a non-random-access iterator. #include <type_traits> #include <iterator> template <class Iterator> void mySort(Iterator begin, Iterator end){ /*The below condition must be true if the 'Iterator' type is a pointer or if it is of Category random_access_iterator_tag. How to make such check?*/ static_assert(some condition,

Is there a way to prevent a class from being derived from twice using a static assert and type trait?

孤街浪徒 提交于 2019-12-01 19:35:56
I realize this is a contrived example, but I want a compile check to prevent this... class A {}; class B : public A {}; class C : public A {}; class D : public B, public C { BOOST_STATIC_ASSERT((is_base_of_once<A,D>::value)) }; The following should work: BOOST_STATIC_ASSERT(((A*)(D*)0 == 0)) If A exists twice, this should rise an ambiguity error, while otherwise the test will always succeed (because it compares two null pointers). When I try to derive a class twice as you have here it does not even compile. (duplicate base type) If you really want to, you an test both your base classes: class

constexpr, static_assert, and inlining

给你一囗甜甜゛ 提交于 2019-12-01 14:53:55
问题 I previously asked about function overloading based on whether the arguments are constexpr. I'm trying to work around the disappointing answer to that question to make a smarter assert function. This is roughly what I am trying to do: inline void smart_assert (bool condition) { if (is_constexpr (condition)) static_assert (condition, "Error!!!"); else assert (condition); } Basically, the idea is that a compile-time check is always better than a run-time check if it's possible to check at

Using std::extent on std::array

亡梦爱人 提交于 2019-12-01 06:42:42
I have a templatized function and I want to static_assert that it's type has a size of three. This code illustrates what I'm trying to do, but doesn't work: template < typename T > void foo( T& param ) { // This line is the one that I need to figure out how to write static_assert( 3 == std::extent< T >::value, "param must have a size of 3" ); } int main( void ) { int cArray[3]; std::array< int, 3 > stdArray; foo( cArray ); foo( stdArray ); } std::extent is defined for built-in arrays. For std::array use std::tuple_size instead. I don't know some trait that works on both, but it's easy to write