2016-09-28 134 views
3

我正在研究two phase name lookup。一个非常合乎逻辑的解释表明,one of the main reasoning是因为它遵循C++哲学尽早捕获错误实例化模板化类的非模板化非模板化方法

我的问题是,为什么没有这个理念,遵循非模板的方法。而不是检查何时以及是否调用方法,为什么不检查模板类实例化时阶段2中的所有非模板化方法?

例如为:

template <class T> 
struct X { 

    auto foo() // non-templated (important) 
    { 
    T t{}; 
    return t.non_existing(); 
    } 
}; 

int main() 
{ 
    X<int> x; // (1) this compiles OK. 

    // somewhere is a galaxy far far away, 
    // maybe deep inside some unrelated code 
    x.foo(); // (2) the error is here 
} 

如果你从来不写(2)程序编译并没有任何问题上运行,虽然foo是实例化X<int>非法的。

我认为线(1)应产生的错误,无论如果你打电话foo与否。

在编写模板类,这可以让漏网之鱼裂缝的错误,直到你最终调用该方法存在问题(2),而不是得到的错误,当你实例化模板类(1)。

此外,健全性检查:如果我实例化X<int>(1)但从未呼叫X<int>::foo(2),代码是否有效?还是像“不合格,不需要诊断”?如果是后者,那么这是更早发现错误的更多理由。

+0

完整性检查:代码(1)有效。至于为什么:想象一下,如果你不得不为非可复制的'T's禁用'std :: vector ',就要写一个拷贝构造函数。 Dtto for'push_back(const T&)'等 – Angew

+0

@Angew我想象的是通过禁用SFINAE方法来管理。 – bolov

回答

6

代码有效。

此功能旨在允许std::vector有一个简单的operator<operator==

该运营商将试图调用<==其元素,一味。如果它是无效的,一旦你在包装vector上调用<==,它将无法编译。

但是,如果你从来没有,在vector将正常工作。

现代C++会建议使用SFINAE条件方法技术或C++ 20需要条款,从而vector只会一个==<,如果它是一个有效的操作。这些技术都没有成熟,当设计vector时,以及具有无效的模板类方法的能力是重要特征。

除了无效代码早期失败之外,有条件地存在==允许包装代码检测==是否可以安全调用:古老的技术不允许这种内省。我不得不编写专门针对标准容器模板的自定义特征来检测至少有一种情况是否可以安全地调用<