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

CPP warning : "‘B’ has a base ‘A<(& str)>’ whose type uses the anonymous namespace" while using a template string

提问人:Ephesiel 提问时间:8/19/2023 更新时间:8/19/2023 访问量:43

问:

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

// 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.hmain.cpptest.cpp

在这篇文章中已经回答了一个类似的问题,但只有一个而不是一个。const char*std::size_t

上面链接的帖子的答案是使用 before 中的关键字并在 .但是使用更正后的代码进行编译时会出现以下错误:externconst char str[]strtest.cppstd::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++ 模板 警告

评论


答:

1赞 273K 8/19/2023 #1

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

inline const char str[] = "ABCD";

lass B : public A<str, std::size(str) - 1> {};

评论

0赞 Ephesiel 8/19/2023
有了这个,我得到以下错误:,你确定它适用于吗?error: invalid use of array with unspecified bounds 246 | -> decltype(__cont.size())const char*
1赞 Jarod42 8/19/2023
@Ephesiel:你有吗?extern const char str[5];
0赞 273K 8/19/2023
知道了,答案已经更新了。
0赞 Ephesiel 8/19/2023
好的,如果我在括号中指定字符串的长度,它就可以工作了。.我在这篇文章中还发现该关键字在我的情况下有效。谢谢。extern const char str[5]inline
0赞 Jarod42 8/19/2023
“GCC(和其他编译器)将 strlen 视为'constexpr'函数,作为语言的扩展。”这可能会使 OP 代码正常工作。