Question: It is a bit strange. I am trying to write a code which detects whether a type is a string object. The char \* or other object types should lead to false not true. The following code gives me: 

> 
> error: template parameters not deducible in partial specialization:
> 
> 
> 

I do not understand what the message means. Even searched online, I cannot figure out how to fix this:

```
#include <iostream>
#include <type_traits>
#include <string>

template <typename T>
struct is_string : std::false_type { };

template <typename T>
struct is_string<std::string> : std::true_type<T> { };

class Temp
{
  int a;
};

int main()
{
    // Expect: false
    std::cout << is_string<int>::value << std::endl;
    std::cout << is_string<char *>::value << std::endl;
    std::cout << is_string<Temp>::value << std::endl;

    // Expect: true
    std::cout << is_string<std::string>::value << std::endl;
    std::cout << is_string<const std::string>::value << std::endl;
    std::cout << is_string<std::string&>::value << std::endl;
}

```

If there is a out of box `std` tool, that's welcome

Answer: 
"Typo" in specialization syntax, it should be:

```
template <>
struct is_string<string> : std::true_type {};

```

To handle `const std::string` or `std::string&`, you might compose with [`std::decay`](https://en.cppreference.com/w/cpp/types/decay)

```
template <typename T>
using is_string_like = is_string<std::decay_t<T>>;

```

or using [`std::is_same`](https://en.cppreference.com/w/cpp/types/is_same):

```
template <typename T>
using is_string_like = std::is_same<std::string, std::decay_t<T>>;

```
The specialization should not include `typename T`, so:

```
template <>
struct is_string<std::string> : std::true_type<T> { };

```

Since you want `const std::string` and `std::string&` and combinations thereof to count as `string` too, you may find it easier to inherit from `integral_constant` instead (which is what `false_type` and `true_type` does).

Example:

```
#include <iostream>
#include <string>
#include <type_traits>

template <typename T>
struct is_string : std::integral_constant<bool,
                                         std::is_same_v<std::string, std::decay_t<T>>> {};

// helper
template<typename T>
inline constexpr bool is_string_v = is_string<T>::value;

```