The problem
I have the following array like container:
template <
class _Tp,
size_t _Size
> class Alphabet {
public:
template <class... _Ts>
constexpr
Alphabet(_Ts&& ... ts)
: m_data(std::forward<_Ts>(ts)...})
{}
private:
_Tp m_data[_Size ? _Size : 1];
}
which I use like this:
constexpr Alphabet<char, 3> abc{'a', 'b', 'c'}; // ok, elements are distinct
However, I would like to be able to tell at compile time if the elements are unique. So in the body of the constructor I would just simply add:
Alphabet(_Ts&& ... ts)
: m_data{std::forward<_Ts>(ts)...}
{
static_assert(is_unique(ts...), "Elements must be distinct!")
}
So now when I write:
constexpr Alphabet<char, 3> abc{'a', 'b', 'b'}; // error! elements are not distinct
What I have attempted
For this I have written the following code, which works at runtime:
template <class _Tp>
constexpr
bool is_one_of(_Tp)
{
return false;
}
template <class _Tp, class... _Ts>
constexpr
bool is_one_of(_Tp t, _Tp f, _Ts... ts)
{
return (t == f) || is_one_of(f, ts...);
}
template <class _Tp>
constexpr
bool is_unique(_Tp)
{
return true;
}
template <class _Tp, class... _Ts>
constexpr
bool is_unique(_Tp t, _Ts... ts)
{
return is_unique(ts...) && !is_one_of(t, ts...);
}
Unfortunately, when attempting to compile I am soon met with the following errors:
error: non-constant condition for static assertion
static_assert(detail::is_unique(ts...),
^
error: 'ts#0' is not a constant expression
I am on C++14. Any help is appreciated!