模板化类的格式错误的非模板化方法的实例化 [英] Instantiation of ill-formed non-templated method of a templated class

查看:238
本文介绍了模板化类的格式错误的非模板化方法的实例化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究两阶段名称查找.一个非常合乎逻辑的解释表明,主要原因之一是遵循C ++的捕获错误的哲学: .

I was researching on two phase name lookup. A very logical explanation shows that one of the main reasoning for it is that follows the C++ philosophy of catching errors as early as possible.

我的问题是,为什么这种哲学没有采用非模板方法.

My question is why isn't this philosophy followed with non-templated methods. Instead of checking when and if the method is called, why not check all non-templated methods in phase 2 when the templated class is instantiated?

例如:

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>是非法的.

If you never write (2) the program compiles and runs without any problems, although foo is illegal for the instantiated X<int>.

我认为第(1)行应该产生错误,无论您是否呼叫foo.

I think that the line (1) should generate error, regardless if you ever call foo or not.

在编写模板化类时,这可以让您跳过错误,直到最终调用该有问题的方法(2),而不是在实例化模板化类(1)时得到错误.

When writing templated classes, this can let slip through the cracks an error until you finally call that problematic method (2), instead of getting the error when you instantiate the templated class (1).

还可以进行完整性检查:如果我实例化X<int>(1)但从不调用X<int>::foo(2),该代码是否有效?还是像格式错误,无需诊断"之类的东西?如果是后者,那么这是更早发现错误的原因.

Also sanity check: is the code valid if I instantiate X<int> (1) but never call X<int>::foo (2)? Or is it something like "ill-formed, no diagnostics required"? If the latter, then this is an even more reason to catch the error earlier.

推荐答案

该代码有效.

此功能旨在允许类似std::vector这样的内容简单地编写operator<operator==.

This feature was designed to permit things like std::vector having an operator< or operator== written simply.

此运算符将尝试盲目调用其元素上的<==.如果无效,一旦在包装的vector上调用<==,它将无法编译.

This operator would try to call < or == on its elements, blindly. If it was invalid, once you called < or == on the wrapping vector it would fail to compile.

但是,如果您从未这样做过,vector就可以正常工作.

But if you never did, the vector would work fine.

现代C ++建议使用SFINAE条件方法技术或C ++ 20 Requires子句,因此vector仅在有效的情况下具有 ==<.在设计vector时,这些技术都没有成熟的,并且拥有在无效的情况下具有模板类方法的功能是重要的功能.

Modern C++ would advise using SFINAE conditional method techniques or C++20 Requires clauses, so vector would only have a == or < if it was a valid operation. None of these techniques where mature when vector was designed, and the ability to have methods of template classes that where not valid was an important feature.

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

On top of early-failure on invalid code, having == conditionally exist permits wrapping code to detect if == is safe to call: the ancient technique does not permit this introspection. I have had to write custom traits that specialize on the standard container templates to detect if < is safe to call in at least one case.

这篇关于模板化类的格式错误的非模板化方法的实例化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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