2

我有以下 C++ 代码,用于计算 Koenig 从 Accelerated C++ 获取的容器的中值。

中位数.h

#ifndef GUARD_median_h
#define GUARD_median_h

#include <stdexcept>
#include <algorithm>
#include <cstddef>

template<class T, class Iterator>
T median (Iterator begin, Iterator end)
{
    size_t size = end - begin;
    if (size == 0)
        throw std::domain_error("median of an empty vector");

    sort(begin, end);

    size_t mid = size/2;

    return size%2 == 0 ? (begin[mid] + begin[mid-1])/2 : begin[mid];
}
#endif

中值测试.cpp

#include <vector>
#include <iostream>
#include "median.h"

using std::vector;  using std::cin;
using std::cout;    using std::endl;

int main()
{
    vector<double> myVec;

    cout << "Please enter integers: ";

    double val;
    while (cin >> val) {
        myVec.push_back(val);
    }

    cout << "The median is: " << median<double>(myVec.begin(), myVec.end()) << endl;

    return 0;
}

这段代码编译并运行得很好。但是,如果我稍作修改以使用数组而不是像这样的向量来测试中值函数...

中值测试数组.cpp

#include <iostream>
#include "median.h"

using std::cin;
using std::cout;    using std::endl;

int main()
{
    double myVec[1000];

    cout << "Please enter integers: ";

    double val;
    size_t i = 0;
    while (cin >> val) {
        myVec[i++] = val;
    }

    cout << "The median is: " << median<double>(myVec, myVec+i) << endl;

    return 0;
}

我收到以下编译错误:

| => g++-6 -I. median_test_array.cpp
In file included from median_test_array.cpp:2:0:
median.h: In instantiation of 'T median(Iterator, Iterator) [with T = double; Iterator = double*]':
median_test_array.cpp:19:60:   required from here
median.h:15:9: error: 'sort' was not declared in this scope
     sort(begin, end);
     ~~~~^~~~~~~~~~~~
median.h:15:9: note: suggested alternative:
In file included from /usr/local/Cellar/gcc/6.2.0/include/c++/6.2.0/algorithm:62:0,
                 from median.h:5,
                 from median_test_array.cpp:2:
/usr/local/Cellar/gcc/6.2.0/include/c++/6.2.0/bits/stl_algo.h:4727:5: note:   'std::sort'
     sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
     ^~~~

如果我为排序 (std::sort) 提供完全限定名称,此错误就会消失,但我想知道为什么在这种情况下我需要一个完全限定名称,而不是在向量示例中。

4

2 回答 2

2

第一个代码是由于所谓的 Argument Dependent Lookup 而编译的。由于std::vector<double>::iterator属于命名空间std,因此该函数sort也在此命名空间中查找。

当您使用指针时,就没有 ADL。因此编译器找不到名称的声明sort

使用限定名称std::sort

于 2016-12-03T01:37:32.940 回答
1

这是一个ADL问题。

对于您的第一个代码示例,似乎实现std::vector::iterator在 namespace 内声明为 class std,然后 ADL 生效,std::sort可以找到带有 type 参数的调用std::vector::iterator

对于您的第二个代码示例,传递给的参数sort只是double*,ADL 不再生效,sort因此找不到名称。

请注意,不保证此类行为;标准没有指定std::vector::iterator应该在哪里实现,它甚至不必是一个类,所以你最好指定 qualifier std::,或者将它与using std::sort;.

于 2016-12-03T01:37:31.993 回答