How to make a variadic is_same?

Use template recursion:

template<typename T, typename... Rest>
struct is_any : std::false_type {};

template<typename T, typename First>
struct is_any<T, First> : std::is_same<T, First> {};

template<typename T, typename First, typename... Rest>
struct is_any<T, First, Rest...>
    : std::integral_constant<bool, std::is_same<T, First>::value || is_any<T, Rest...>::value>
{};

static_assert(is_any<int, char, double, int>::value, "error 1");   // OK
static_assert(is_any<int, char, double, short>::value, "error 2"); // error

Nice and concise with C++17:

template <class T, class... Ts>
struct is_any : std::disjunction<std::is_same<T, Ts>...> {};

And the dual:

template <class T, class... Ts>
struct are_same : std::conjunction<std::is_same<T, Ts>...> {};

A variation that uses fold expressions:

template <class T, class... Ts>
struct is_any : std::bool_constant<(std::is_same_v<T, Ts> || ...)> {};

template <class T, class... Ts>
struct are_same : std::bool_constant<(std::is_same_v<T, Ts> && ...)> {};

In C++17 you have an even nicer solution, using template variables and fold expressions:

template<class T, class... Rest>
inline constexpr bool are_all_same = (std::is_same_v<T, Rest> && ...);

And the usage is also simpler than all other examples:

are_all_same<T, A, B, C>

No ::value, no parentheses!