I want to create a template that will take variadic number of a specific class that contains a string. When i try to make such a template class, it throws no instance of constructor "A" matches the argument list
class A:
template<template_string s>
class A {};
class B:
template<A... As>
class B {};
template_string.h:
template<size_t _N>
struct template_string {
char c_str[_N];
constexpr template_string(const char(&text)[_N]) {
std::copy(text, text _N, c_str);
}
constexpr std::string std_str() const noexcept {
return std::string(c_str);
}
constexpr std::string_view str_view() const noexcept {
return std::string_view(c_str);
}
constexpr size_t length() const noexcept {
return _N-1;
}
};
I want to make it explicitly through templates and classes. What would i need to do so that I can construct class B like this:
B<A<"text">(), A<"other text">(),....> b;
CodePudding user response:
This is an instance of the "most vexing parse" problem, where it looks like you are declaring a function type instead of creating on object. Here's a complete working example, where I've replaced the function call ()
with the uniform initialization syntax {}
:
#include <cstddef>
#include <string>
using std::size_t;
template<size_t _N> requires (_N >= 1)
struct template_string {
char c_str[_N];
constexpr template_string(const char(&text)[_N]) {
std::copy(text, text _N, c_str);
}
constexpr std::string std_str() const noexcept {
return std::string(c_str);
}
constexpr std::string_view str_view() const noexcept {
return std::string_view(c_str, length());
}
constexpr size_t length() const noexcept {
return _N-1;
}
};
template<template_string s>
class A {};
template<A... As>
class B {};
int
main()
{
[[maybe_unused]] B<A<"text">{}, A<"other text">{}> b;
}
The other thing I did was create the string_view
with the length of the string, just in case the string contains NUL bytes, as in "hello\0there"
.