按照斯科特·迈耶(Scott Meyer)的“现代C++”中的一个示例,我将利用模板来减少std::array的大小。我偶然尝试编译myUsage函数用法。

#include <array>
#include <iostream>

template <typename T, std::size_t N>
constexpr std::size_t arraySize(T (&) [N]) noexcept
{
        return N;
}

void scottUsage()
{
        int b[5];
        std::array<short, arraySize(b)> c;
        std::cout << arraySize(b) << " = " << c.size() << "\n";
}

template <typename T, std::size_t N>
void myUsage(T & arr [N])
{
        for (auto i=0; i<arraySize(arr); i++)
                std::cout << arr[i] << "\t";
}

int main()
{
        scottUsage();

        int a[7];
        myUsage(a);
}


因此出现两个问题:
  • (附带问题)(&)的作用是什么?删除会触发error: creating array of references,似乎是禁止的
  • myUsage签名出了什么问题?
  • 最佳答案

    myUsage()需要使用T (&arr) [N]

    template <typename T, std::size_t N>
    void myUsage(T (&arr) [N])
    

    括号告诉编译器该引用适用于数组本身,而不适用于数组的元素类型。

    另外,arraySize()myUsage()都应引用const数据:

    template <typename T, std::size_t N>
    constexpr std::size_t arraySize(const T (&) [N]) noexcept
    ...
    template <typename T, std::size_t N>
    void myUsage(const T (&arr) [N])
    

    顺便说一句,从C++ 17开始不需要arraySize(),请改用 std::size() :

    #include <array>
    #include <iostream>
    #include <iterator>
    
    void scottUsage()
    {
        int b[5];
        std::array<short, std::size(b)> c;
        std::cout << std::size(b) << " = " << c.size() << "\n";
    }
    
    template <typename T, std::size_t N>
    void myUsage(const T (&arr) [N])
    {
        for (auto i = 0; i < std::size(arr); ++i)
            std::cout << arr[i] << "\t";
        /* better:
        for (const T &value : arr)
            std::cout << value << "\t";
        */
    }
    
    int main()
    {
        scottUsage();
        int a[7];
        myUsage(a);
    }
    

    09-11 22:10