问题
I am trying to use clang++
to expand the template code from this post. Here is what I come up with.
constexpr unsigned int requires_inRange(unsigned int i, unsigned int len) {
return i >= len ? throw i : i;
}
class StrWrap
{
unsigned size_;
char * const begin_;
public:
template< unsigned N >
constexpr StrWrap( const char(&arr)[N] ) : begin_(arr), size_(N - 1) {
static_assert( N >= 1, "not a string literal");
}
constexpr char operator[]( unsigned i ) {
return requires_inRange(i, size_), begin_[i];
}
constexpr operator const char *() {
return begin_;
}
constexpr unsigned size() {
return size_;
}
};
constexpr unsigned count( StrWrap str, char c, unsigned i = 0, unsigned ans = 0 )
{
return i == str.size() ? ans :
str[i] == c ? count(str, c, i + 1, ans + 1) :
count(str, c, i + 1, ans);
}
int main(int argc, char const *argv[])
{
static_assert( count("dude", 'd') == 2, "d != 2" );
return 0;
}
However, the code from the blog post is not compiling:
/usr/bin/clang++ -Xclang -ast-print -fsyntax-only test_debugger2.cpp > main.exe
test_debugger2.cpp:12:48: error: cannot initialize a member subobject of type 'char *const' with an lvalue of type 'const char [5]'
constexpr StrWrap( const char(&arr)[N] ) : begin_(arr), size_(N - 1) {
^ ~~~
test_debugger2.cpp:38:26: note: in instantiation of function template specialization 'StrWrap::StrWrap<5>' requested here
static_assert( count("dude", 'd') == 2, "d != 2" );
^
test_debugger2.cpp:38:20: error: static_assert expression is not an integral constant expression
static_assert( count("dude", 'd') == 2, "d != 2" );
^~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.
I could find this related question Cannot initialize a member subobject of type 'const signed char *' with an lvalue of type 'const char [X]', but I did not get how I could fix it.
By using the flags -Xclang -ast-print -fsyntax-only
I am only asking clang
to expand the templates and print their expansion to stdout: Compile-time 'String' Manipulation with Variadic Templates
I am trying to learn to do string computations, i.e., string splitting, string concatenation, find, replace, cut, etc, at compile time with C++ Templates which are said to be Turing Complete: C++ templates Turing-complete?, then, I am taking examples as that blog post and expanding them with clang
to see how they work and how I could use them to solve any compile time (possible) computations with templates.
This is my compiler version:
clang version 8.0.1 (tags/RELEASE_801/final)
Target: x86_64-unknown-windows-cygnus
Thread model: posix
InstalledDir: /usr/bin
How could I fix the template expansion from that blog post?
回答1:
This
char * const begin_;
is a const
pointer to char
(the pointer is const, not the thing it points to). This
const char(&arr)[N]
is a reference to an array of N
elements of type const char
. The element of the array are const. You cannot have a pointer to non-const point into an array of const elements (at least not without brute force). You need to either make your pointer a const char*
or make your array an array of non-const elements…
I guess you mean to write
const char* begin_;
Note: starting with C++17, you can just use std::string_view…
来源:https://stackoverflow.com/questions/59418505/how-to-deduce-the-size-of-a-compile-time-a-const-char-string-with-c-templates