gpt4 book ai didi

c++ - 静态函数模板和 MISRA C++

转载 作者:太空狗 更新时间:2023-10-29 23:03:23 26 4
gpt4 key购买 nike

以下具有特殊化的函数模板只能在同一个 .cpp 文件中使用,所以我想将其设为 static。以下代码使用 MS Visual C++ 2008 和 GCC 4.8.1 编译(没有警告)并按预期工作。 (在第 5 行和第 11 行的开头添加 static 会导致 GCC 发出错误,但 MSVC 不会。)

 1  template <class T>
2 static bool foo(const T param);
3
4 template <>
5 bool foo<int>(const int param)
6 {
7 return doSomethingWithInt(param);
8 }
9
10 template <>
11 bool foo<bool>(const bool param)
12 {
13 return doSomethingWithBool(param);
14 }

但是,MISRA C++ 检查器提示:

  • (MISRA2008.3-3-2) 将 static 关键字应用于 'foo' 的声明 (1)
  • (MISRA2008.3-3-2) 将静态关键字应用于“foo”的声明 (5)
  • (MISRA2008.2-10-5-b) 正在重用标识符“foo”(5)
  • (MISRA2008.3-3-2) 将静态关键字应用于“foo”的声明 (11)
  • (MISRA2008.2-10-5-b) 标识符“foo”被重用 (11)

我试图找出问题所在,并在 C++ standard quote 中找到了提示:

For a function call that depends on a template parameter, if the function name is an unqualified-id but not a template-id, the candidate functions are found using the usual lookup rules (3.4.1, 3.4.2) except that:

  • For the part of the lookup using unqualified name lookup (3.4.1), only function declarations with external linkage from the template definition context are found.

这是否意味着编译器丢弃了 static 规范并且没有办法在 C++03 中实际制作静态函数模板?

最佳答案

显式特化使函数(或类)的定义能够根据模板特化的模板参数进行更改。它们不是“新声明”。

GCC 警告在显式特化 7.1.1/1 上使用 static 是正确的:

A storage-class-specifier shall not be specified in an explicit specialization (14.7.3) or an explicit instantiation (14.7.2) directive.

因此,对于 5 和 11,您的 MISRA 检查器应用“静态”的建议似乎是错误的,我还质疑 foo 是否以某种方式被重用。只有一个实体 foo 碰巧有不同的定义。

具有内部链接的函数在这个翻译单元之外是不可见的。只有在通过重载决策选择了主模板本身后,才会考虑显式特化。

考虑以下几点:

template <typename T>
void f (T); // #1

template <>
void f<int*> (int*); // #2

template <typename T>
void f (T*); // #3

void b() {
int * i;
f(i); // Calls #3
}

查找 f 找到两个模板,#1 - f(T) 和 #3 - f(T*)T 推导为 int* #1 和 int #3 (14.8.2)。重载解析发生在特化 #1 -> f(int*) 和 #3 -> f(int*) 中。两者都不是最佳匹配,因此会发生部分排序 (14.5.6.2)。偏序的结果是 #3 比 #1 更专业。因此,编译器选择#3 作为最佳匹配。 注意:显式特化没有参与上述任何步骤。

如果没有#3。那么#1 将被重载决议选为最佳匹配。然后编译器搜索 specialziations 列表。推导的参数列表 int* 与显式规范中使用的参数列表匹配,因此调用定义 #2。

关于引用的段落:

  • For the part of the lookup using unqualified name lookup (3.4.1), only function declarations with external linkage from the template definition context are found.

此限制起源于模板可以导出时 (C++ '03 14/6)。这个想法是允许在当前翻译单元之外定义模板。此查找限制有助于确保更改要导出的未导出模板不会导致不同含义的程序。

关于您提出的这对静态函数模板和 C++ '03 意味着什么的问题,事实上,据我所知,只有一家编译器供应商曾经完整地实现过导出模板。无论如何,大多数编译器供应商很有可能已经很长时间以来一直遵循 C++ 11 建议。从 MISRA 合规性的角度来看,最好的选择是遵循 metal's 中的建议。评论你的问题。将模板放在未命名的命名空间中。

在 C++ '03 中,名称将无法从翻译单元外部调用,对于 C++ '11 之后,它们具有隐式的内部链接 (3.5/4):

An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage.

关于c++ - 静态函数模板和 MISRA C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25788127/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com