为什么C ++ 03需要模板参数具有外部链接? [英] Why did C++03 require template parameters to have external linkage?

查看:160
本文介绍了为什么C ++ 03需要模板参数具有外部链接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 03中,用作模板参数的符号必须具有外部链接;这个限制在C ++ 11中被删除,如在 上一个问题

In C++03, symbols used as template arguments must have external linkage; this restriction was removed in C++11, as explored in this previous question:


在C ++ 03中,模板参数不能有内部连结:

In C++03, template arguments could not have internal linkage:


[C ++ 03:14.6.4.2/1]:对于依赖于模板参数的函数调用,如果函数名是 unqualified-id 而不是 template-id ,则使用常用的查找除了:

[C++03: 14.6.4.2/1]: 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:


  • 对于使用非限定名称查找的查找部分(3.4.1),只找到具有来自模板定义上下文的外部链接的函数声明

  • 对于使用关联命名空间3.4.2),只有在模板定义上下文或模板实例化上下文中找到具有外部链接的函数声明。

em>

[..]

这已更改(问题#561:依赖名称查找中的内部链接函数)在C ++ 11中:

This was changed (issue #561: "Internal linkage functions in dependent name lookup") in C++11:


[C ++ 11:C.2.6]: 14.6.4.2

更改:允许具有内部链接的函数的相关调用
b 原因:过度约束,简化重载解析规则。

[C++11: C.2.6]: 14.6.4.2
Change: Allow dependent calls of functions with internal linkage
Rationale: Overly constrained, simplify overload resolution rules.

导致:


11:14.6.4.2/1]:对于依赖于模板参数的函数调用,使用常用的查找规则(3.4.1,3.4.2,3.4.3)找到候选函数,除了:

[C++11: 14.6.4.2/1]: For a function call that depends on a template parameter, the candidate functions are found using the usual lookup rules (3.4.1, 3.4.2, 3.4.3) except that:


  • 对于使用非限定名称查找的查找部分(3.4.1)

  • 对于使用关联命名空间(3.4.2)的查找部分, ,只能找到在模板定义上下文或模板实例化上下文中找到的函数声明。

  • For the part of the lookup using unqualified name lookup (3.4.1) or qualified name lookup (3.4.3), only function declarations from the template definition context are found.
  • For the part of the lookup using associated namespaces (3.4.2), only function declarations found in either the template definition context or the template instantiation context are found.

/ em>

[..]

(找出缺少的外部链接资格。)

问题#561(依赖名称查找中的内部链接函数),导致在C ++ 11中删除限制的提案询问:

Issue #561 ("Internal linkage functions in dependent name lookup"), the proposal that led to the restriction being removed in C++11, asks:


此外,是否真的有必要从查找中排除内部链接函数?

Furthermore, is it really necessary to exclude internal linkage functions from the lookup? Doesn't the ODR give implementations sufficient latitude to handle this case without another wrinkle on name lookup?

对于后面的答案:


该组的共识是,应该通过查找找到内部链接函数( [..]如果通过重载决议选择,它们可能会导致错误。)

The consensus of the group was that [..] internal-linkage functions should be found by the lookup (although they may result in errors if selected by overload resolution).






问题



限制的原始实际理由是什么?

似乎必须因为原来的标准措辞超出了它的限制查找符号与外部链接。

It seems like there must have been one, since the original standard wording went out of its way to limit lookup to symbols with external linkage.

这只是[内部链接功能]可能导致如果通过重载分辨率选择错误,并且通过2000年代的意见转移了这是多么重要?或者做了其他改变,也许作为一个不同的C ++ 11功能的新措辞的间接后果?

Is it just that "[internal-linkage functions] may result in errors if selected by overload resolution", and that through the 2000s opinion shifted over how important this was? Or did something else change, perhaps as an indirect consequence of new wording elsewhere for a different C++11 feature?

推荐答案

将怀疑它与C ++ 98的臭名昭着的 export 模板特性相关。想想吧。一旦允许模板定义出现在单独的翻译单元中,但在指定模板参数(即,模板被实例化)之前仍然不能真正编译,您将进入这个暮光区,其中TU具有模板的定义,具有实例化的TU必须服从链接器可见性规则(即,分离模型),同时在过载分辨率方面共享它们的上下文。该问题的解决方案是仅允许在依赖名称查找中具有外部链接的函数。

I would suspect it's related to the infamous export template feature of C++98. Think about it. Once you allow the possibility of template definitions appearing in separate translation units, but still not truly compilable until the template arguments are specified (i.e., the template is instantiated), you get into this twilight zone where the TU with the definition of the template and the TU with the instantiation have to obey linker-visibility rules (i.e., separation model) while sharing their contexts in terms of overload resolution. The solution to that problem is to allow only functions with external linkage in the dependent name lookups.

这里是一个示例。导出模板的一个较少知名的特性是,你可以在模板的TU中有一些内部链接的函数或类(例如,标记为 static 未命名的命名空间)。如果具有实例化的TU具有内部链接功能,那么会与模板的TU中的模糊不清或者可能被其取代,那么该怎么办?这是一个超现实的问题,我知道,这是出口模板的奇妙世界。避免非常令人惊讶的行为的唯一方法是排除所有内部链接函数从查找。还要考虑没有人清楚地知道如何实际导出模板,如果没有这个限制,它可能看起来更不可能实现。

Here's an example. One of the lesser known "feature" of exported templates is that you could have, in the template's TU, some functions or classes with internal linkage (i.e., marked static or in an un-named namespace). What if the TU with the instantiation has a internal-linkage function too, one that would be ambiguous with or possibly superceded by the one in the template's TU? That's a bit of a surreal problem, I know, it's the bizarro world of exported templates. The only way to avoid very surprising behavior is to rule out all internal-linkage functions from the lookups. Consider also that no-one had a clear idea of how to actually implement exported templates, and it would probably seem even more impossible to implement without this restriction.

一旦导出的模板出来,对依赖名称查找的限制似乎显然没有用,它被毫无争议地取出。

And so, once exported templates are out, the restriction on dependent name lookups seems clearly useless and it was taken out without much debate. At least, that makes perfect sense to me, but, of course, it's speculation.

这是一个具体的例子:

// in exptemp.h
export template <typename T> bool is_valid(T value);

// in exptemp.cpp
namespace {
  bool is_space(char c) {
    return (c == ' ') || (c == '\t');
  };
};

template <typename T>
bool is_valid(T value) {
  return is_space(value);
};

// in test.cpp
#include "exptemp.h"

namespace {
  bool is_space(char c) {
    return (c == ' ') || (c == '\t') || (c == '\n');
  };
};

int main() {
  char c = '\n';
  return is_valid(c);   // will this return 0 or 1 ?!?!?
};

这篇关于为什么C ++ 03需要模板参数具有外部链接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆