为什么C++重载解析不能推导出嵌套模板类型?

问题描述 投票:0回答:1

这个所谓的重复解释了为什么不允许这样做的机制,并显示了它无法工作的极端情况,但未能解决为什么 C++ 在它可以工作的情况下拒绝允许它的问题。

tl;dr;我知道C++不能做到这一点,并且我知道如何通过ADL解决它并且我不会问这个。我不知道的是为什么语言设计选择(或被迫)不允许这样做。


较长版本:

以下代码适用于除最后一种情况之外的所有情况:

template <class T>
struct A { struct R {}; };

template <>
struct A<double> { using R = int; };

void Fn(int);

template <class T>
void Fn(typename A<T>::R v);

////////////////////////////////

void Test() {
    A<double>::R d;
    A<int>::R v;

    Fn(0);  // Works; calls Fn(int)
    Fn(d);  // Wroks; calls Fn(int)
    Fn(v);  // Fails; expected to call Fn<int>(A<int>::R)
}

它失败了,因为语言无法为

T
的模板重载推断模板参数
Fn
,以便将
typename A<T>::R
变成
A<int>::R
。对于人类来说,在这种情况下,很明显
T
应该是
int
,但 C++ 的规则不允许做出这样的推论。

我的实际问题:

是什么促使或迫使 C++ 的设计者施加这种限制?

我怀疑答案是,在实际解决类模板之前“猜测”类模板将具有嵌套类型在技术或哲学上是有问题的,或者在现有编译器中实现该逻辑在架构上是禁止的。也就是说,只有第一个问题是一个基本问题,我实际上并不明白为什么其中任何一个都一定是正确的,这表明我错过了一些有趣的东西。 顺便说一句:除非 Bjarne Stroustrup 或 90 年代 C++ 标准委员会的某个人看到了这一点,否则我得到的最佳答案可能就是消息灵通的猜测。


附注


有几个人指出,当

A<R>::S

作为

using

 别名提供时(特别是通过显式专业化),生成的正确/完全解析的类型可能根本不会提及 
A<>
虽然有道理,但这不是我要问的情况。

    这仅在类型推导过程中必须不区分类型和类型别名的假设下才有意义。这可能是标准委员会做出的选择,但这是一个选择,而不是强加给他们的。
  1. 即使在当前情况和规则下,显式专业化和类型别名也可能会导致一些
  2. 集市和意外结果
  3. ,如
  4. this template<int I> struct Int; template<> struct Int<0> { using T = int; }; template<> struct Int<1> { using T = long; }; template<int I> struct C { using T = typename Int<I % 2>::T; static int Mine(); friend int Get(T) { return C::Mine(); } }; void Test() { C<0> c0; // Ok C<1> c1; // This doesn't break anything. C<2> c2; // Delete this and things work. /* error: redefinition of 'int Get(C<2>::T)' note: 'int Get(C<0>::T)' previously declared here */ }
在一般情况下,正如评论中所讨论的,不可能
c++ language-design overload-resolution
1个回答
0
投票
元函数

Ttypename A<T>::R

。如果确实存在具有该名称的嵌套类型,那么当然可以推断出它;据推测,这种情况被认为太狭隘而无法激励,特别是如果用户可能不理解该功能的局限性和脆弱性。
提出支持可行案例的论文

时,委员会的感觉是这将是一个“突破性”的改变,在某种程度上不寻常的意义上,它将允许演绎(及其相关的内省权力)适用于以前不受此类分析影响的类型。人们不想重命名他们的嵌套类型(为了源兼容性而破坏 ABI,甚至在旧名称下给定类型别名)以防止语义发生变化,以及为任何专业化的成员执行诸如

customize 之类的操作的能力类模板(通过重载或部分特化)不被认为是引人注目的。

© www.soinside.com 2019 - 2024. All rights reserved.