• <bdo id='M4sbV'></bdo><ul id='M4sbV'></ul>
      <i id='M4sbV'><tr id='M4sbV'><dt id='M4sbV'><q id='M4sbV'><span id='M4sbV'><b id='M4sbV'><form id='M4sbV'><ins id='M4sbV'></ins><ul id='M4sbV'></ul><sub id='M4sbV'></sub></form><legend id='M4sbV'></legend><bdo id='M4sbV'><pre id='M4sbV'><center id='M4sbV'></center></pre></bdo></b><th id='M4sbV'></th></span></q></dt></tr></i><div id='M4sbV'><tfoot id='M4sbV'></tfoot><dl id='M4sbV'><fieldset id='M4sbV'></fieldset></dl></div>

      <small id='M4sbV'></small><noframes id='M4sbV'>

    1. <legend id='M4sbV'><style id='M4sbV'><dir id='M4sbV'><q id='M4sbV'></q></dir></style></legend>

      <tfoot id='M4sbV'></tfoot>
    2. 为什么 C++ 参数范围会影响命名空间内的函数查找?

      Why does C++ parameter scope affect function lookup within a namespace?(为什么 C++ 参数范围会影响命名空间内的函数查找?)
        • <tfoot id='ynQTR'></tfoot>
          <legend id='ynQTR'><style id='ynQTR'><dir id='ynQTR'><q id='ynQTR'></q></dir></style></legend>
          <i id='ynQTR'><tr id='ynQTR'><dt id='ynQTR'><q id='ynQTR'><span id='ynQTR'><b id='ynQTR'><form id='ynQTR'><ins id='ynQTR'></ins><ul id='ynQTR'></ul><sub id='ynQTR'></sub></form><legend id='ynQTR'></legend><bdo id='ynQTR'><pre id='ynQTR'><center id='ynQTR'></center></pre></bdo></b><th id='ynQTR'></th></span></q></dt></tr></i><div id='ynQTR'><tfoot id='ynQTR'></tfoot><dl id='ynQTR'><fieldset id='ynQTR'></fieldset></dl></div>
              <tbody id='ynQTR'></tbody>

              <bdo id='ynQTR'></bdo><ul id='ynQTR'></ul>

              1. <small id='ynQTR'></small><noframes id='ynQTR'>

                本文介绍了为什么 C++ 参数范围会影响命名空间内的函数查找?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                这对我来说似乎有点倒退,但它有效:

                This seems a little backwards to me but it works:

                #include <iostream>
                
                namespace nTest
                {
                  struct cTest {};
                
                  void fTest(cTest& x)
                  {
                    std::cout << "nTest::fTest(cTest&) called" << std::endl;
                  }
                }
                
                int main(void)
                {
                  nTest::cTest x;
                  fTest(x); //Weird! fTest is resolved since its parameter belongs to nTest.
                  return 0;
                }
                

                通常,您需要 nTest:: 才能访问 fTest,但它属于 nTest 的参数似乎将 nTest 添加到搜索 fTest 的可能范围列表中.参数范围影响函数查找对我来说似乎很奇怪.

                Normally, you would need nTest:: in order to access fTest, but its parameter which belongs to nTest appears to add nTest to the list of possible scopes in which to search for fTest. It seems odd to me that the parameter scope influences the function lookup.

                这在 GCC 中编译得很好,但我想知道这种用法是否可移植?这种范围机制的官方定义是什么?

                This compiles fine in GCC, but I'm wondering is this usage portable? What is the official definition of this scoping mechanism?

                推荐答案

                即 ADL(Argument Dependent Lookup)或 Koenig Lookup(针对功能设计者).该功能的目的是在许多情况下相同的命名空间将包含可以应用于这些类型的类型和函数,所有这些都符合 接口.如果 ADL 没有到位,您必须使用 using 声明将标识符带入范围,否则您必须限定调用.

                That is ADL (Argument Dependent Lookup) or Koenig Lookup (for the designer of the feature). The purpose of the feature is that in many cases the same namespace will contain types and functions that can be applied to those types, all of which conform the interface. If ADL was not in place, you would have to bring the identifiers into scope with using declarations or you would have to qualify the calls.

                这变成了一场噩梦,因为该语言允许运算符重载.考虑以下示例:

                This becomes a nightmare since the language allows for operator overloads. Consider the following example:

                namespace n {
                   struct test {};
                   test operator+( test, test const & ); // implemented
                };
                int main() {
                   n::test a,b;
                   n::test c = a + b;  //without ADL: c = n::operator+( a, b )
                }
                

                虽然看起来有点尴尬,但考虑到 n 可能是 std 命名空间,test 可能是 ostreamoperator+ 可以是 operator<<:

                While it might seem like an awkward situation, consider that n might be the std namespace, test might be ostream, and operator+ could be operator<<:

                int main( int argc, char** ) {
                   std::cout << "Hi there, there are " << argc << " arguments" << std::endl;
                }
                

                如果没有 ADL,对 operator<< 的调用必须是显式的,而且您必须知道它们中的哪一个是作为自由函数实现的,而不是作为方法实现的.你知道 std::cout <<嗨" 正在调用一个免费函数,std::cout <<<5 正在调用成员函数?没有多少人意识到这一点,而且说真的,几乎没有人关心.ADL 会向您隐藏这一点.

                Without ADL, the calls to operator<< would have to be explicit, and moreover you would have to know which of them is implemented as a free function versus a method. Did you know that std::cout << "Hi" is calling a free function and std::cout << 5 is calling a member function? Not many people realize it, and seriously, almost no one cares. ADL hides that from you.

                这篇关于为什么 C++ 参数范围会影响命名空间内的函数查找?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                相关文档推荐

                Constructor initialization Vs assignment(构造函数初始化 Vs 赋值)
                Is a `=default` move constructor equivalent to a member-wise move constructor?(`=default` 移动构造函数是否等同于成员移动构造函数?)
                Has the new C++11 member initialization feature at declaration made initialization lists obsolete?(声明时新的 C++11 成员初始化功能是否使初始化列表过时了?)
                Order of constructor call in virtual inheritance(虚继承中构造函数调用的顺序)
                How to use sfinae for selecting constructors?(如何使用 sfinae 选择构造函数?)
                Initializing a union with a non-trivial constructor(使用非平凡的构造函数初始化联合)

                <tfoot id='20izN'></tfoot>

                      <tbody id='20izN'></tbody>

                        • <bdo id='20izN'></bdo><ul id='20izN'></ul>
                          <i id='20izN'><tr id='20izN'><dt id='20izN'><q id='20izN'><span id='20izN'><b id='20izN'><form id='20izN'><ins id='20izN'></ins><ul id='20izN'></ul><sub id='20izN'></sub></form><legend id='20izN'></legend><bdo id='20izN'><pre id='20izN'><center id='20izN'></center></pre></bdo></b><th id='20izN'></th></span></q></dt></tr></i><div id='20izN'><tfoot id='20izN'></tfoot><dl id='20izN'><fieldset id='20izN'></fieldset></dl></div>
                        • <small id='20izN'></small><noframes id='20izN'>

                        • <legend id='20izN'><style id='20izN'><dir id='20izN'><q id='20izN'></q></dir></style></legend>