Creating compile-time errors for invalid data types in a template class?

I use C ++ to create a string class. I want the class to accept only char and wchar_t data types, and I want the compiler to catch any invalid data types at compile time using #error. I do not like to use assert (). How can i do this?

+3
source share
2 answers

You can use a static statement. Boost provides one .

Maybe something like:

#include <boost/type_traits.hpp>
#include <boost/static_assert.hpp>

template <typename T>
class my_string
{
public:
    // ...
private:
    BOOST_STATIC_ASSERT((boost::is_same<T, char>::value ||
                          boost::is_same<T, wchar_t>::value));
};

int main(void)
{
    my_string<char> chstr;
    my_string<wchar_t> wstr;

    // fails
    my_string<int> istr;
}

If you cannot use Boost, you can easily remake static-assert and is_same:

// static assert failure
template <bool Predicate>
struct STATIC_ASSERT_FAILURE;

template <>
struct STATIC_ASSERT_FAILURE<true> {}; // only true is defined

// static assert test
template <unsigned TestResult>
struct static_assert {};

// static assert macro
#define STATIC_ASSERT(x) typedef static_assert< \
                          sizeof(STATIC_ASSERT_FAILURE<(x)>)> \
                          _static_assert_test_

// value is true if T and U are the same type
template <typename T, typename U>
struct is_same
{
    static const bool value = false;
};

template <typename T>
struct is_same<T, T>
{
    static const bool value = true;
};

template <typename T>
class my_string
{
public:
    // ...
private:
    STATIC_ASSERT((is_same<T, char>::value || is_same<T, wchar_t>::value));
};

int main(void)
{
    my_string<char> chstr;
    my_string<wchar_t> wstr;

    // fails
    my_string<int> istr;
}

, , . , , __COUNTER__ .

GCC 4.4, Visual Studio 2008.

+12

. , .

template <class C> class limiter;

char wchar_t .

template <>
class limiter<char>
{
public:
    typedef char limit_type;
}

template <>
class limiter<wchar_t>
{
public:
    typedef wchar_t limit_type;
}

:

template <class TYPE>
class mystring
{
   typedef typename limiter<TYPE>::limit_type limit_type;
   ...
}

char wchar_t, .

+5

Source: https://habr.com/ru/post/1721749/


All Articles