1

Let's say I've got a function:

template <typename T>
void foo(const T& arg) {
   ASSERT(is_valid<T>::value == true);
   // ...
}

Where is_valid check if T is either a string or an integer. I can easily make structures that can do that for me:

template <typename T>
struct is_integer { static const bool value = false; };
template <>
struct is_integer<int> { static const bool value = true; };

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

And then use both of these structure to check the argument:

template <typename T>
struct is_valid { 
    static const bool value = is_string<T>::value || is_integer<T>::value; 
};

However it seems I miss some string types. Is there a C++ type that target all string types? Is there already a structure or function that can do that for me?

I got:

  • std::string
  • char*
  • char[]

in my is_string structure but it doesn't seem to be enough. I haven't passed const and & (references) as it is not tested that way: from a const T& argument, only T is tested.

YSC
  • 38,212
  • 9
  • 96
  • 149
baptiste
  • 1,107
  • 2
  • 15
  • 30
  • What makes you think you are missing some types? Did you pass something that should have been detected as a string but wasn't? What did you pass? – nwp Oct 06 '17 at 13:58
  • 1
    What do you consider as string ? `/*const*/char[N]`, `std::wstring`, `QString`, `vector`, ... – Jarod42 Oct 06 '17 at 13:59
  • 1
    http://en.cppreference.com/w/cpp/string/basic_string this may or may not help – Charles Oct 06 '17 at 13:59
  • 3
    Think about using #include . std::remove_cv, std::is_same, std::is_constructible – Andrey Nasonov Oct 06 '17 at 13:59
  • 1
    You first must define a definition of a string (Jarod's comment). A suggestion, `T` is a string iff `std::string(T const&)` exists; i.e. `is_constructible::value == true` (Andrey's comment). – YSC Oct 06 '17 at 14:07
  • @AndreyNasonov I don't use C++11 unfortunately @nwp When I call `foo("bar")`, the assertion fails. @Jarod42 A string could be anything to me. The thing is I don't know how `"const static"` is seen by the compiler... And I don't really know where is the information. @Charles I tried using `std::basic_string` in my struct but it is not seen as type. – baptiste Oct 06 '17 at 14:11

1 Answers1

3

If the following definition of a string suits you:

T is a string if and only if it can be used to construct an std::string.

Then, you could define is_string<T> with:

template <typename T>
using is_string = std::is_constructible<std::string, T>;

And is_constructible is definable in C++98 :)


Demo on coliru:

#include <string>
#include <type_traits>

template <typename T>
using is_string = std::is_constructible<std::string, T>;

#include <iostream>
int main()
{
    std::cout << std::boolalpha
        << is_string<const char*>::value << "\n"
        << is_string<volatile char*>::value << "\n"
        << is_string<std::string>::value << "\n"
        ;
}

Output:

true
false
true

YSC
  • 38,212
  • 9
  • 96
  • 149