CPP 警告:使用模板字符串时“‘B’有一个基‘A<(& str)>’,其类型使用匿名命名空间”

问题描述 投票:0回答:1

这是我能给出的最简单的代码:

// 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)
是由远远落后的另一个模板类完成的。

我怎样做才能不出现警告或错误?

c++ templates warnings
1个回答
1
投票

std::strlen()
不能在 constexpr 上下文中使用。您可以使用
std::size()
。此外,您还需要创建
str
数组
inline
让编译器知道
str
数组大小。

inline const char str[] = "ABCD";

lass B : public A<str, std::size(str) - 1> {};
© www.soinside.com 2019 - 2024. All rights reserved.