Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a type is std::basic_string<T> in compile time in C++

Tags:

c++

templates

I have is_string defined as follow in my C++ code:

#include <string>

template <typename T>
struct is_string
{
    static const bool value = false;
};

template <class T, class Traits, class Alloc>
struct is_string<std::basic_string<T, Traits, Alloc>>
{
    static const bool value = true;
};

int main()
{
    std::cout << is_string<std::string>::value << std::endl;
    std::cout << is_string<std::wstring>::value << std::endl;

    return 0;
}

It is true for both std::string and std::wstring.

But I need a predicate like this:

is_string<char, std::string>::value //to be true
is_string<char, std::wstring>::value //to be false
is_string<wchar_t, std::string>::value //to be false
is_string<wchar_t, std::wstring>::value //to be true

Is it possible to implement it?

like image 411
Alexey Starinsky Avatar asked Aug 15 '18 16:08

Alexey Starinsky


2 Answers

Try this:

template <typename T, typename S>
struct is_string
{
  static const bool value = false;
};

template <class T, class Traits, class Alloc>
struct is_string<T, std::basic_string<T, Traits, Alloc>>
{
  static const bool value = true;
};

In this specific case, a simpler solution would be:

template<class T, class S>
using is_string = std::is_same<T, typename S::value_type>;

(However, it doesn't check that the second type is actually a string, if that is fine with you - this solution checks if the second type is any container that holds elements of the first type)

like image 199
riv Avatar answered Sep 30 '22 05:09

riv


Firstly, you need to make is_string taking two template parameters.

template <typename T, typename = void>
struct is_string
{
    static const bool value = false;
};

template <class T, class Traits, class Alloc>
struct is_string<std::basic_string<T, Traits, Alloc>, void>
{
    static const bool value = true;
};

Then

template <class T, template <typename, typename, typename> class STRING>
struct is_string<T, STRING<T, std::char_traits<T>, std::allocator<T>>>
{
    static const bool value = true;
};

LIVE

like image 27
songyuanyao Avatar answered Sep 30 '22 05:09

songyuanyao