Here is the simplest code I can give:
// main.cpp
#include "test.h"
int main() { return 0; }
// test.h
#pragma once
#include <cstring>
const char str[] = "ABCD";
template <
const char* str,
std::size_t N
>
class A {};
class B : public A<str, strlen(str)> {};
// test.cpp
#include "test.h"
When I compile, I get twice the following warning:
test.h:13:7: warning: ‘B’ has a base ‘A<(& str), 4>’ whose type uses the anonymous namespace [-Wsubobject-linkage]
13 | class B : public A<str, strlen(str)> {};
| ^
The reason why I get it twice is because test.h
is included twice, once in main.cpp
and once in test.cpp
.
A similar question has already been answering in this post, but there was only a const char*
and not a std::size_t
too.
The answer of the above linked post was to use the extern
keyword before const char str[]
and define str
in the test.cpp
. But with std::size_t
the compilation with the corrected code gives the following error:
test.h:13:31: error: ‘strlen(((const char*)(& str)))’ is not a constant expression
13 | class B : public A<str, strlen(str)> {};
| ~~~~~~^~~~~
Of course my code is more complicated than that and the main problem is that my object only need a const char*
, the strlen(str)
is done by another templated class far behind.
How can I do things to not have warnings or errors?