【发布时间】:2014-11-27 10:48:34
【问题描述】:
在我对this question 的回答之后,在 C++11 和 C++14 中:
[C++11, C++14: 25.5/2]:内容与标准 C 库头<stdlib.h>相同,但有以下例外:
[C++11, C++14: 25.5/3]:函数签名:bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *));替换为两个声明:
extern "C" void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); extern "C++" void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));两者都具有与原始声明相同的行为。
然而,
[C++11, C++14: 7.5/5]:如果两个声明将具有相同名称和参数类型列表 (8.3.5) 的函数声明为相同命名空间的成员,或者将具有相同名称的对象声明为相同命名空间的成员,则声明给名称不同的语言链接,程序格式错误;如果声明出现在不同的翻译单元中,则不需要诊断。 [..]
这是缺陷吗?
【问题讨论】:
-
答案取决于这两个函数是否具有相同的参数。如果链接是类型的一部分,
compar在两个示例中都有不同的类型......虽然如果是,我想要一些简单的方法来为类型声明它,我不知道。 -
@Deduplicator 在标准 C++ 中,您可以使用模板别名。
template <typename R, typename...T> using CxxFunc = R(T...); extern "C" { template <typename R, typename...T> using CFunc = R(T...); }。将compar声明为CFunc<int, const void *, const void *>和CxxFunc<...>。大多数实现都拒绝它,因为它们不允许extern "C"块中的模板,但它是完全有效的。限制是模板不能有extern "C"链接,而不是模板不能出现在extern "C"块中。模板别名没有语言链接,所以没关系。 -
在 C++98 25.4/3 中也是一样的(
qsort是 25.4/4)
标签: c++ c++11 language-lawyer c++14 bsearch