C++ 有没有一种方法可以避免头文件中使用的constexpr函数在没有额外名称空间的情况下进入全局范围?

C++ 有没有一种方法可以避免头文件中使用的constexpr函数在没有额外名称空间的情况下进入全局范围?,c++,header-files,constexpr,C++,Header Files,Constexpr,我有一个头文件,其代码如下所示: constexpr uint32 GenTag(const char tag[5]) { ... } class SomeClass { static constexpr uint32 TAG1 = GenTag("smth"); static constexpr uint32 TAG2 = GenTag("abcd"); }; //constexpr needed for switch-case statement 问题是函数GenTag()属

我有一个头文件,其代码如下所示:

constexpr uint32 GenTag(const char tag[5]) { ... }

class SomeClass
{
   static constexpr uint32 TAG1 = GenTag("smth");
   static constexpr uint32 TAG2 = GenTag("abcd");
};
//constexpr needed for switch-case statement
问题是函数
GenTag()
属于全局范围,如果可能的话,我希望避免它

我想在类中声明它,但在
constexpr
中不可能这样做(这里的解释是:)


C++在头的末尾是否有类似“un声明”函数(可能是一些宏技巧)?或者其他我错过的选择?如果没有更好的方法存在,我可能会使用额外的(可能过多的)命名空间,但是想问是否还有其他的想法。

< P> >在C++中没有办法“声明”函数或变量(头文件或没有-头文件只包含在当前翻译单元中)。您需要使用名称空间,或者将
GenTag
设置为宏。你可以用“代码”>“ununf”宏定义< /COD>来定义宏。

< P>没有办法在C++中“声明”函数或变量(头文件或没有-头文件只包含在当前翻译单元中)。您需要使用名称空间,或者将
GenTag
设置为宏。您可以使用
#undef MACRONAME

来取消宏的定义,在继承的结构中将
GenTag()
定义为
静态constexpr
方法如何

如果希望
GenTag()
仅在
SomeClass
中可用,可以将其设置为
private
,并在包含
GenTag()的类中将
SomeClass
定义为
friend

我是说。。。如下

#include <iostream>

struct SomeClass;

class foo
 {
   static constexpr char GenTag(const char tag[5])
    { return tag[0]; }

   friend SomeClass;
 };

struct SomeClass : public foo
 {
   static constexpr char TAG1 = GenTag("smth");
   static constexpr char TAG2 = GenTag("abcd");
 };

int main()
 {
   std::cout << "Tag1: " << SomeClass::TAG1 << std::endl;
   std::cout << "Tag2: " << SomeClass::TAG2 << std::endl;

   // compilation error: 'GenTag' is a private member of 'foo'
   // static constexpr char TAG3 = foo::GenTag("wxyz");
 }
#包括
结构类;
福班
{
静态constexpr char GenTag(const char标记[5])
{返回标记[0];}
在课堂上交朋友;
};
struct SomeClass:public foo
{
静态constexpr char TAG1=GenTag(“smth”);
静态constexpr char TAG2=GenTag(“abcd”);
};
int main()
{

std::cout将
GenTag()
定义为继承结构中的
静态constexpr
方法怎么样

如果希望
GenTag()
仅在
SomeClass
中可用,可以将其设置为
private
,并在包含
GenTag()的类中将
SomeClass
定义为
friend

我的意思是……如下所示

#include <iostream>

struct SomeClass;

class foo
 {
   static constexpr char GenTag(const char tag[5])
    { return tag[0]; }

   friend SomeClass;
 };

struct SomeClass : public foo
 {
   static constexpr char TAG1 = GenTag("smth");
   static constexpr char TAG2 = GenTag("abcd");
 };

int main()
 {
   std::cout << "Tag1: " << SomeClass::TAG1 << std::endl;
   std::cout << "Tag2: " << SomeClass::TAG2 << std::endl;

   // compilation error: 'GenTag' is a private member of 'foo'
   // static constexpr char TAG3 = foo::GenTag("wxyz");
 }
#包括
结构类;
福班
{
静态constexpr char GenTag(const char标记[5])
{返回标记[0];}
在课堂上交朋友;
};
struct SomeClass:public foo
{
静态constexpr char TAG1=GenTag(“smth”);
静态constexpr char TAG2=GenTag(“abcd”);
};
int main()
{

STD::CUT< P>如果有人也会遇到这样的问题,我建议您不要在头上使用这种CONEXPRO,而是考虑直接在CPP文件中声明它,这样就可以避免不必要的全局范围污染。

或者如果有多个地方可以使用这些常量,然后单独地对它们进行任何分类,并将该文件与包含类定义标头分开包含。

< P>如果任何人都会遇到这样的问题,我建议您不要在头中使用这种CONEXPRPR,而是考虑声明定义。它直接放在cpp文件中,并且只放在cpp文件中。这样,您肯定可以避免不必要的全局范围污染


或者,如果有多个地方可以使用这些常量,则在没有任何类的情况下为它们创建一个单独的HEARD,并将该文件与包含类定义标头分开包含。

您真的需要
GenTag
在标头中吗?静态类成员需要在cpp文件中的类之外进行初始化,以便efine
GenTag
在cpp文件中,因此它不存在于头文件中。嗨,Nathan。这对于constexpr不是真的,因为它们只在内联中定义(所以是的,我需要它在头文件中)。我需要constexpr而不是这里的const,因为它在switch case语句中使用。可能需要将它添加到问题中这里有什么问题,真的吗?这不像是多个定义的问题。嗨,StoryTeller。我关心它,因为可能有其他函数接受同名GenTag的const char数组,该函数有多个类的特定版本头文件中是否真的需要
GenTag
?静态类成员需要在cpp文件中的类之外初始化,因此您只能在cpp文件中定义
GenTag
,因此它不存在于头文件中。嗨,Nathan,这对于constexpr来说不是真的,因为它们仅是内联定义的(所以是的,我需要它在标题中)。我需要constexpr而不是这里的const,因为它在switch case语句中使用。可能需要将它添加到问题中这里有什么问题,真的吗?这不像是多个定义的问题。嗨,StoryTeller。我关心它,因为可能有其他函数接受同名GenTag的const char数组,该函数有多类的特定版本起初我认为它会像visual studio intellisence一样工作,但编译器没有。问题与问题中提供的链接相同,即foo::GetTag()的定义只有在TAG1=…声明定义中使用后才会处理。这肯定是一个有趣的想法,但如果我没有弄错的话,它不会起作用。在这两种情况下,谢谢,这是一个很好的实验try@Andrew-有趣。如果您从
SomeClass
继承
foo
,您会得到相同的错误?max66没有测试它,但是al最确定的是“是”,因为编译器仅在处理所有声明(即使它们是内联的)之后才处理任何类方法的定义但constexpr只能内联定义,这就是我出现问题的原因——除了实现部分(即cpp文件)之外,不可能在任何其他地方使用任何类内定义的constexpr,我认为它可以在fir上工作