数组指针与数组引用之间的区别

时间:2015-08-23 13:37:57

标签: c++ c++11

我想编写一个区分数组和指针的函数。这是为了计算文字字符串的大小。我试过了:

template<typename Ty>
void f(const Ty* rhs) {
    std::cout << __FUNCTION__ << rhs << std::endl;
}

template<typename Ty, size_t Dm>
void f(const Ty(&rhs)[Dm]) {
    std::cout << __FUNCTION__ << rhs << std::endl;
}

int main(int, char*[]) {
    const char arr0[] = "test2";
    const char* ptr = "test3";
    const char arr6[6] = "test4";
    f("test1");
    f(arr0);
    f(ptr);
    f(arr6);
    return 0;
}

但是编译器(VS2013)告诉我这个调用是不明确的。任何提示?

提前致谢。

4 个答案:

答案 0 :(得分:3)

不幸的是,电话不明确。

作为解决方法,您可以添加额外的图层:

template<typename Ty>
void f_pointer(const Ty* rhs) {
    std::cout << __FUNCTION__ << rhs << std::endl;
}

template<typename Ty, size_t Dm>
void f_array(const Ty(&rhs)[Dm]) {
    std::cout << __FUNCTION__ << rhs << std::endl;
}

template<typename T>
std::enable_if_t<std::is_array<T>::value>
f(const T&t)
{
    f_array(t);
}

template<typename T>
std::enable_if_t<!std::is_array<T>::value>
f(const T&t)
{
    f_pointer(t);
}

Live Demo

答案 1 :(得分:1)

Jarod42的替代方法(可行)是使用类模板专业化:

#include <iostream>
#include <type_traits>


template <typename T, bool is_array>
struct f_helper {
    static void print_type (T& arg) {
        std::cout << arg << " is an array\n";
    }
};

template <typename T>
struct f_helper<T, false> {
    static void print_type (T arg) {
        std::cout << arg << " is not an array\n";
    }
};

template <typename T>
void f (T& arg) {
    f_helper<T, std::is_array<T>::value>::print_type (arg);
}


int main(int, char*[]) {
    const char arr0[] = "test2";
    const char* ptr = "test3";
    const char arr6[6] = "test4";
    f("test1");
    f(arr0);
    f(ptr);
    f(arr6);
    return 0;
}

Live demo

答案 2 :(得分:0)

在函数模板的第二个重载中更改对指针的引用:

template<typename T, size_t S> void f(T(&)[S]){
  cout << "array with size " << S << "\n";
}

template <typename T> void f(T*&) {
  cout << "pointer \n";
}  

Live Demo

答案 3 :(得分:-3)

我不相信你可以尝试按照自己的方式尝试。以下陈述评估同样的事情:

  • int* var

  • int var[]

这完全是语法糖的问题。此外,在函数头上向数组添加大小只有警告用户预期的数组大小的好处。因此,这两者也是等价的(就编译器而言):

  • void f(int* v)

  • void f(int v[8])