c ++传递数组直接到函数

时间:2015-11-06 00:26:48

标签: c++ arrays g++ parameter-passing

  bool foo(const char* arg, const char* str[]){
    for (int i=0; i < (signed)sizeof(str); i++){
      if(strcmp(arg, str[i])) == 0){
        return true;
      }
    }
    return false;
  }

    int main(){
      foo("c", {"a", "b", "c"});
      return 0;
    }

我想直接将const char *数组传递给函数,如此处所示。但我一直收到错误:cannot convert '<brace-enclosed initializer list>' to 'const char**'

4 个答案:

答案 0 :(得分:4)

虽然有一种方法可以使用模板并通过引用传递C数组,但我不确定这是否是您真正想要的:example

在C ++ 11中,我更倾向于使用std::intializer_list来使调用foo("c", {"a", "b", "c"})按预期工作:

#include <initializer_list>

bool foo(const char* arg, std::initializer_list<const char*> strings) {
    for (const char* str : strings) {
        /* ... */
    }
}

虽然我们正在考虑,但您应该考虑使用C ++的字符串工具而不是从C继承的字符串:

#include <initializer_list>
#include <string>

bool foo(const std::string& arg, std::initializer_list<std::string> strings) {
    for (const auto& str : strings) {
        if (arg == str) {
            return true;
        }
    }
    return false;
}

请注意,std::initializer_list不拥有它提供访问权限的值,因此如果您想要存储它,请使用std::vector之类的适当容器。

此外,如果您想要在arg中检查是否存在str, 为什么不使用std::find

#include <algorithm>
#include <initializer_list>
#include <string>

bool foo(const std::string& arg, std::initializer_list<std::string> strings) {
    return std::find(strings.begin(), strings.end(), arg) != strings.end();
}

答案 1 :(得分:0)

使用字符指针指针(char **)来实现此目的。您不能将参数声明为数组,但可以将数组传递给函数,因为它们将转换为双指针。

答案 2 :(得分:0)

虽然建议在使用C ++时删除C风格的编程,并使用stl容器代替,但我想提及以下&#34; one-liner&#34;工作原理:

bool foo(const char* arg, const char* const* str, size_t siz) {
  for (size_t i = 0; i < siz; i++)
      if (!strcmp(arg, str[i])) return true;
  return false;
}

int main() {
  cout << foo("c", array<char*, 3> { "a", "b", "c" }.data(), 3);
  system("pause");
}

令人惊讶的惊喜是如果我们将foo的第二个参数定义为const char**,编译器(VS2015)会大喊并说:

  

bool foo(...):无法从&#39; char **&#39;转换参数2到&#39; const char **&#39;

:O型 无法从非const转换为const ???这对任何人都有意义吗?

编辑:@NeilKirk在评论中解释道。正常。因此签名应为:

bool foo(const char* arg, const char* const* str, size_t siz) 

一切都按预期工作。

答案 3 :(得分:0)

您也可以通过模板函数通过引用传递数组,这样您就可以在编译时检测它的大小(请注意,在您的情况下,数组会衰减为指针,因此sizeof不会做你的想法)。例如:

#include <iostream>
#include <cstring>

template<int N>
bool foo(const char* arg, const char* (&str)[N])
{
    for (std::size_t i = 0; i < N; i++) {
        if (std::strcmp(arg, str[i]) == 0) {
            return true;
        }
    }
    return false;
}

int main() {
    const char* arr[] = {"abc", "de"};
    std::cout << std::boolalpha << foo("de", arr);
}

Live on Coliru

顺便说一下,尝试使用C ++标准库中的算法和std::string而不是strcmp()和原始C字符串:

#include <algorithm>
#include <iostream>
#include <vector>

bool foo(const std::string arg, const std::vector<std::string>& str)
{
    return std::find(str.begin(), str.end(), arg) != str.end();
}

int main() 
{
    std::cout << std::boolalpha << foo("de", {"abc", "de"});
}

Live on Coliru