Consider a BasicCharp class with two constructors:
template <class CharType>
class BasicCharp {
public:
using value_type = CharType;
using pointer = value_type*;
public:
//1
template<size_t SIZE>
constexpr BasicCharp(value_type (&str)[SIZE]) noexcept
: m_Length(SIZE)
, m_String(str) {}
//2
constexpr BasicCharp(pointer string) noexcept
: m_Length(countElems(string))
, m_String(string) {}
private:
size_t m_Length;
pointer m_String;
};
Constructing:
BasicCharp<const char> str = "test";
This calls constructor 2, however if there is no constructor 2, this does call constructor 1.
How to keep constructor 2, but enforce using constructor 1 if possible?
A c++17 solution is preferred, but any standart is welcome.
The goal is to deduce string literal's size at compile time, but if a pointer is passed, size should be calculated by the constructor.
Not exactly the same, but you might tag dispatch, something like:
template <typename > struct Tag{};
template <class CharType>
class BasicCharp {
// ...
public:
template<typename T>
constexpr BasicCharp(const T& str) noexcept : BasicCharp(str, Tag<T>{})
{
// Or alternatively, use if constexpr here
}
private:
template<std::size_t SIZE>
constexpr BasicCharp(const value_type (&str)[SIZE],
Tag<value_type[SIZE]>) noexcept
: m_Length(SIZE)
, m_String(str) {}
constexpr BasicCharp(const value_type*string, Tag<const value_type*>) noexcept
: m_Length(countElems(string))
, m_String(string) {}
};