我在C ++中有几个字符串数组,它们定义为const字符串
const string ABC[5] = {“1”,”2”,”3”,”4”,”5”};
const string DEF[3] = {“1”,”2”,”3”};
我需要将它们中的每一个传递给与该伪代码相似的相同函数:
void doSomething(string strArray[])
{
// loop to access all strings in the array and do something .
};
但是当调用它时,它传递给函数时会给我关于类型的错误
doSomethign(ABC);
doSomethign(DEF);
这是生成的错误
错误C2664'无效花名册:: strInput1(std :: string [])':无法转换 参数1从“ const std :: string [5]”到“ std :: string []”
我也尝试过使用const类型,但是我不确定自己在做什么错。
答案 0 :(得分:5)
ABC
和DEF
作为参数传递时衰减到const string*
类型的指针,该指针与strArray[]
类型不兼容。
此外,如果要在doSomething
函数内部循环遍历数组,则还需要传递数组的大小,以便知道数组的范围。
由于ABC
和DEF
的大小不同,因此这里需要使用的是函数模板。
这里是循环遍历T
数组并打印元素的示例。
template<typename T, size_t N>
void doSomething(T (&arr)[N])
{
// loop to access all elements in the array and print them.
for(auto const& var: arr)
cout << var << '\n';
}
请参见Demo here。
如果它只是一个std::string
数组,则可以在非类型参数N
上进行参数化,该参数是数组的大小。在这种情况下,功能模板将为:
template<size_t N>
void doSomething(const std::string (&arr)[N])
{
// loop to access all strings in the array and do something .
for(auto const& str: arr)
cout << str << '\n';
}
答案 1 :(得分:1)
我不同意使用C样式的数组,而是看到std::array
或std::vector
。与此有关的两个主要问题是大小信息的丢失和指针行为的衰减。
也就是说,您的根本问题是const正确性。
为简单起见,我将基于C样式变体旁边的std :: vector将代码重写为等效代码。请参阅P.W的答案,以了解为什么尺寸信息很重要以及如何处理它。我的答案更多地集中在不引入要求您公开算法的模板化方法上。
以下代码定义了字符串的常数向量。一旦定义了const,接收该对象的对象就不应更改。 (忽略可变和const_cast)。
const std::vector<std::string> ABC = {"1","2","3","4","5"};
const std::string ABC[] = {"1","2","3","4","5"};
由于此对象是作为const创建的,因此它永远无法更改,并且const_cast是未定义的行为。 std::string
中未使用该变量,因此内部状态无法更改。
那么您的函数怎么了?
void doSomething(std::vector<std::string> &strArray);
void doSomething(std::string strArray[], size_t size);
此签名接受字符串的非常量向量。不允许将const对象传递给此函数,因为此函数签名允许修改原始实例。
因此,如何解决:更正签名以不允许任何修改。如果不修改其输入参数,则是首选方法。
void doSomething(const std::vector<std::string> &strArray);
void doSomething(const std::string strArray[], size_t size);
或者,如果需要修改,请在创建时删除const:
std::vector<std::string> ABC = {"1","2","3","4","5"};
std::string ABC[] = {"1","2","3","4","5"};
当我使用std :: vector而不是C样式数组时,我们甚至得到了C样式数组无法实现的第三种可能性:按值传递。
void doSomething(std::vector<std::string> strArray)
在这种情况下,该函数获取数据的副本。如果必须在不影响调用者的情况下对向量进行一些操作,这可能会很有用。例如:将所有字符串转换为大写字母或对向量进行排序。
答案 2 :(得分:-1)
如果要传递const数组,请尝试将其也写在函数中,并用星号代替括号。
void doSomething(const string *strArray)
{
// loop to access all strings in the array and do something .
};