对于某些函数,“无法将 'T [S]' 与 'std::vector<int>' 匹配”,但不能匹配其他具有相同参数列表的函数

dan*_*9er 3 c++ templates types

对于一个家庭作业,我试图创建自己的版本std::findstd::beginstd::end,和std::size

我写了一些看起来像这样的代码:

#include <vector>

template <typename I, typename T>
I find(const I& beg, const I& end, const T& sought)
    {/* ... */}

template <typename T, size_t S>
T* begin(T (&a)[S])
    {return &a;}

template <typename T, size_t S>
T* end(T (&a)[S])
    {return &a + S;}

template <typename T, size_t S>
constexpr size_t size(T (&)[S])
    {return S;}

int main()
{
    std::vector<int> vec = {0, 1, 2, 3};

    // ...

    // test not-found case (and `size()`)
    find(begin(vec), end(vec), size(vec));

    // ...

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

(size_t应该隐式转换为int)

但是,当我编译时,clang 会出现以下错误:

$ clang++ -o program ./*.cpp -std=c++11 -Wall -Wextra -Wpedantic -Wconversion -Wnon-virtual-dtor
./main.cpp:##:##: error: no matching function for call to 'size'
    find(begin(vec), end(vec), size(vec)
    ^~~~
./main.cpp:##:##: note: candidate template ignored: could not match 'T [S]' against 'std::vector<int>'
constexpr size_t size(T (&)[S])
                 ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

真正让我感到困惑的是,size()begin()/end()具有完全相同的模板结构和参数列表,但前者会引发编译错误,而后者在给出相同输入时不会。

我不认为不同的返回类型是问题所在,因为如果是find()这样就会抱怨,而不是size().

那么size()与其他函数有什么不同,它会在模板结构、参数列表和输入相同的情况下抛出这个错误?

Chr*_*odd 7

你无begin/ end/size模板匹配,因为他们只匹配原始阵列(类型T[S](),而不是该类型您正在使用std::vector<T>)。您只会收到一个错误,因为调用beginend将匹配函数std::beginand std::end,由于参数依赖查找。没有std::size函数(在 C++11 中),所以唯一可能的匹配size是你的size函数不匹配,所以你会得到一个错误。

  • 需要明确的是,有一个 [`std::size`](https://en.cppreference.com/w/cpp/iterator/size) *现在*,但这个问题已经过去了(`- std=c++11`)。如果将其调整为“-std=c++17”,问题中的代码将按原样工作。 (3认同)