1

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;
1
  • Added the tag of appropriate C++ version for template<template_string s>. Commented Jul 9, 2022 at 22:51

1 Answer 1

5

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".

Sign up to request clarification or add additional context in comments.

8 Comments

The issue with many users like @stgr2gpns, who ask questions on SO, they do not read whole error messages, they stop reading on the first line. If OP had read the error till the end, they would see note: ambiguous template argument for non-type template parameter is treated as function type
I don't know about this particular case, but in general my experience is that clang++ often doesn't include the relevant information you want, like how a template is being instantiated. g++ does, but g++'s errors are so verbose that they scare beginners off to clang++. So I think the advice when something doesn't compile is first switch to g++, then slog through all the detailed error messages to find what is actually wrong. (I can often help even seasoned clang++ programmers by just compiling with g++ and reading the errors...)
I do not think OP is using Clang that is still unable to use std::string in constexpr.
@273K g++ doesn't seem to support constexpr std::string either. However, the corrected code compiles with both clang++ and g++, because it never requires a constexpr string.
Clang can't compile.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.