6

我这里有这段代码。

#include <iostream>
using namespace std;

template <typename T> inline T bigArry(const T data[5])
{
    T level = data[0];
    for(T item : data) // error C2143: syntax error : missing ',' before ':' (1st)
    { //error C2143: syntax error : missing ';' before '{' (3rd)
        if(level<item){ level=item; }
    }
    return  level;
}

int main()
{
    int data[5]={//five variables}
    cout << bigArry(data);//see reference to function template instantiation 'T bigArry<int>(const T [])' being compiled with [ T=int] (2nd)

    return 0;
}

函数 bigArry() 返回 5 个元素的数组中的最大值。

问题是当我使用基于范围的循环时,它会给我代码中提到的错误。但是当我使用通常的 for 时,一切都会恢复正常。我的意思是,对我来说语法看起来不错,我看不到问题所在。我正在使用 Visual Studio 2010。

我想问的另一件事是关于内联函数。目前我正在阅读 C++ Primer Plus 第 6 版。我什么时候知道函数太大而无法内联?是否有代码应该多短的标准?或者,当我们“认为”没问题时,我们是否使用内联函数?

4

2 回答 2

7

该参数data不是函数模板中的数组。它实际上是一个指针。

这个功能

template <typename T> inline T bigArry(const T data[5])

与此完全相同

template <typename T> inline T bigArry(const T *data)

根本没有区别。

这就是您的代码给出编译错误的原因。

这里有几个修复:

  • 您可以通过引用接受参数,如:

    template <typename T> 
    inline T bigArry(const T (&data)[5]) //NOTE &
    

    那应该行得通。但这看起来很麻烦。也许,使用下一个。

  • 或者您可以使用它(如@yzt 建议的那样):

    template <typename C> 
    inline auto bigArry(C const & data) -> decltype(data[0])
    

    这比上面的(和下面的)更干净,也更灵活。除了传递数组之外,您还可以传递任何容器,只要data[0]它定义明确并且意味着它应该表示的意思。

  • 或者,如果您愿意,您可以std::array<T, 5>用作:

    template <typename T> 
    inline T bigArry(const std::array<T,5> & data) 
    

希望有帮助。

于 2013-06-29T16:40:13.163 回答
6

这是因为数组类型在用作函数参数或作为函数参数传递时会衰减为指针。换句话说,您的函数签名等效于

template <typename T> inline T bigArry(const T* data)

基于范围的for循环传递data给全局std::begin()std::end()函数,以使迭代器(分别)指向容器的第一个和最后一个元素。

当然,没有接受指针std::begin()的全局函数和函数,它们也不能被有意义地定义:如何仅给定一个指向其第一个元素的指针来确定容器的结尾?std::end()

您可以使用std::array而不是 C 数组(std::array是围绕 C 数组的零开销包装器),并相应地修改您的调用函数:

template <typename T> inline T bigArry(std::array<T, 5> data)
//                                     ^^^^^^^^^^^^^^^^
{
    T level = data[0];
    for(T item : data)
    {
        if(level<item){ level=item; }
    }
    return  level;
}

int main()
{
    std::array<int, 5> data = {1,2,3,4,5};
//  ^^^^^^^^^^^^^^^^^^^^^^^
    std::cout << bigArry(data);

    return 0;
}

这是一个活生生的例子

于 2013-06-29T16:39:32.737 回答