C++ 用于管理c+中特定于平台的代码的内联命名空间技术+;

C++ 用于管理c+中特定于平台的代码的内联命名空间技术+;,c++,platform-specific,inline-namespaces,C++,Platform Specific,Inline Namespaces,我见过使用#ifdef宏(例如Eigen库)来管理特定于平台的代码,但没有见过使用“内联名称空间”来管理特定于平台的代码 下面的github repo给出了具体的代码和示例用法。 我想知道这是否是一个可行的技术使用,或者是否有任何陷阱,我无法看到。下面是代码片段: #include <stdio.h> namespace project { // arm/math.h namespace arm { inline void add_() {printf("

我见过使用#ifdef宏(例如Eigen库)来管理特定于平台的代码,但没有见过使用“内联名称空间”来管理特定于平台的代码

下面的github repo给出了具体的代码和示例用法。

我想知道这是否是一个可行的技术使用,或者是否有任何陷阱,我无法看到。下面是代码片段:

#include <stdio.h> 

namespace project { 
  // arm/math.h 
  namespace arm { 
    inline void add_() {printf("arm add\n");}  // try comment out 
  } 

  // math.h 
  inline void add_() { 
    // 
    printf("common add\n"); 
    // 
  } inline namespace platform {inline void add() {add_();}} 


  inline void dot_() { 
    // 
    add(); 
    // 
  } inline namespace platform {inline void dot() {dot_();}} 
} 

int main() { 
 project::dot(); 
 return 1; 
} 
#包括
命名空间项目{
//arm/math.h
名称空间臂{
内联void add{printf(“arm add\n”);}//尝试注释
} 
//数学
内联无效添加{
// 
printf(“公共添加\n”);
// 
}内联命名空间平台{inline void add(){add_u();}}
内联空点{
// 
添加();
// 
}内联命名空间平台{inline void dot(){dot_u();}}
} 
int main(){
项目::点();
返回1;
} 
输出:

$g++func.cpp-Dplatform=common/a、 出去 公共添加

$g++func.cpp-Dplatform=arm/a、 出去
arm add

至少有两种方法可以实现相同的结果。第一个是名称空间。第二个-在类中使用静态函数

使用名称空间:

#include <stdio.h>

namespace GenericMath
{
    void add();
    void dot();
}

namespace ArmMath
{
    void add();

    using GenericMath::dot;
}

namespace GenericMath
{
    void add() 
    {
        printf("generic add");
    }

    void dot() 
    {
        Math::add();
        printf("generic dot");
    }
}

namespace ArmMath
{
    void add() 
    {
        printf("arm add");
    }

    using GenericMath::dot;
}

int main()
{
    Math::dot();
    return 1;
}
#包括
命名空间通用路径
{
无效添加();
空点();
}
名称空间ArmMath
{
无效添加();
使用GenericMath::dot;
}
命名空间通用路径
{
void add()
{
printf(“一般添加”);
}
空点()
{
数学::添加();
printf(“通用dot”);
}
}
名称空间ArmMath
{
void add()
{
printf(“arm添加”);
}
使用GenericMath::dot;
}
int main()
{
数学::点();
返回1;
}
课程:

#include <stdio.h>

class GenericMath
{
public:
    static void add();
    static void dot();
};

class ArmMath : public GenericMath
{
public:
    static void add();
};

void GenericMath::add() 
{
    printf("generic add");
}

void GenericMath::dot() 
{
  printf("generic dot");
  Math::add();
}

void ArmMath::add() 
{
  printf("arm add");
}

int main()
{
    Math::add();
    Math::dot();
    return 1;
}
#包括
类GenericMath
{
公众:
静态void add();
静态空穴点();
};
类ArmMath:public GenericMath
{
公众:
静态void add();
};
void GenericMath::add()
{
printf(“一般添加”);
}
void GenericMath::dot()
{
printf(“通用dot”);
数学::添加();
}
void ArmMath::add()
{
printf(“arm添加”);
}
int main()
{
数学::添加();
数学::点();
返回1;
}

IMO内联命名空间会使代码可读性降低且过于冗长。

问题在于,与
#ifdef
不同,编译器仍会编译所有不适用于当前平台的代码


因此,您不能使用它来处理特定于平台的API。

虽然链接到源代码很好,但您也应该在此处复制并粘贴一段最小的代码片段(并正确设置格式!),以演示您所描述的内容。不使用它是因为内联名称空间是一项新功能,并且没有得到广泛支持,但这种情况是它们存在的主要原因之一。这并不奇怪,也不是什么把戏。@JonathonReinhart用代码片段更新了它。@CollinDauphinee我见过它被用于或提到用于版本控制,但不是用于选择特定于平台的代码,所以好奇。你也可以这样做,w/o
inline namespace
。只需制作
通用
arm
命名空间,并将相同的函数放在那里。另一种方法是使它们成为类,而不是名称空间。优势-您可以共享通用功能并覆盖特定平台(针对每个平台)。好吧,您不能完全避免预处理器。但如果只使用预处理器,它会非常麻烦。即使是有问题的
#define
也用于选择正确的名称空间。这是正确的,但在给定的示例中,预处理器选择的是启用的变量,但只是将其他变量从默认查找集中删除,而不是对编译器完全隐藏。在许多情况下,这可能是一件好事(例如,避免在未启用的路径上发生比特腐烂),但它确实存在一个限制。这个问题特别是内联名称空间与
#ifdef
的比较。我不认为这个问题意味着完全避免使用
#ifdef
。我将其理解为仅预处理器与预处理器+内联名称空间的对比。也许作者能澄清一下吗?问题是“给定技术中的陷阱”。给定的技术依赖于内联名称空间使静态名称解析找到所需的特定于平台的代码,并将其与在Eigen库中使用
#ifdef
进行对比。