这是我能给出的最简单的代码:
// 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"
编译时,我收到两次以下警告:
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)> {};
| ^
我得到两次的原因是因为
test.h
被包含了两次,一次在main.cpp
,一次在test.cpp
。
类似的问题已经在这篇文章中回答过,但只有一个
const char*
,也没有std::size_t
。
上述链接帖子的答案是在
extern
之前使用 const char str[]
关键字,并在 str
中定义 test.cpp
。但使用 std::size_t
时,使用更正后的代码进行编译会出现以下错误:
test.h:13:31: error: ‘strlen(((const char*)(& str)))’ is not a constant expression
13 | class B : public A<str, strlen(str)> {};
| ~~~~~~^~~~~
当然,我的代码比这更复杂,主要问题是我的对象只需要一个
const char*
,strlen(str)
是由远远落后的另一个模板类完成的。
我怎样做才能不出现警告或错误?
std::strlen()
不能在 constexpr 上下文中使用。您可以使用std::size()
。此外,您还需要创建 str
数组 inline
让编译器知道 str
数组大小。
inline const char str[] = "ABCD";
lass B : public A<str, std::size(str) - 1> {};