My aim is to create my own analogue of std::basic_string
but with some additional conditions. I want my AnyString<CharType, Traits>
to be convertible from std::basic_string<CharType, AnyOtherTraits, AnyAlloc>
but I want to disable this constructor for some CharType such that basic_string<CharType>
does not exist (compile).
I tried to do something like that:
template<typename OtherTraits, typename Alloc, typename =
std::enable_if_t<!std::is_array_v<char_type> &&
std::is_trivial_v<char_type> &&
std::is_standard_layout_v<char_type>>>
AnyString(const std::basic_string<char_type, OtherTraits, Alloc>&);
And I have ColouredChar
, which does not meet the conditions listed inside enable_if_t
.
Now, when I'm trying to call the disabled constructor :
std::basic_string<ColouredChar> de("string"_purple);
ColouredString d(de);
I do not only get the compile errors from basic_string
but also very strange one, telling me that completely different PRIVATE constructor constructor cannot convert its parameter from basic_string
.
Is there any way to make these compile errors more readable? Or at least explain whether there's anything here to worry about.
Basic example for constructor restriction using concepts (not your traits)
#include <type_traits>
#include <string>
// declare your own concept
template<typename type_t>
concept my_concept = std::is_convertible_v<type_t, std::string>; // just a demo concept
class ColouredString
{
public:
// then you can limit your constructor to types satisfying that concept
ColouredString(const my_concept auto& /*arg*/)
{
}
~ColouredString() = default;
};
int main()
{
// ColouredString str{ 1 };
ColouredString str{ "hello world!" };
return 0;
}