C++ char*[] 到 char** 的转换 [英] C++ char*[] to char** conversion

查看:45
本文介绍了C++ char*[] 到 char** 的转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个简单的代码,可以在没有错误/警告的情况下进行编译:

I have this simple code that compiles without errors/warnings:

void f(int&, char**&){}

int main(int argc, char* argv[])
{
    f(argc, argv);
    return 0;
}

以及下一个无法编译的类似代码:

And next similar code that doesn't compile:

void f(int&, char**&){}

int main()
{
    int argc = 2;
    char* argv[] = { "", "", nullptr };
    f(argc, argv); 
    //@VS2013 error: cannot convert argument 2 from 'char *[3]' to 'char **&'
    //@GCC error: invalid initialization of non-const reference of type 'char**&' from an rvalue of type 'char**'
    return 0;
}

为什么在第一个示例中char*[]可以转换为char**&而在第二个示例中不能转换?在编译时知道大小是否重要?

Why char*[] can be converted to char**& in the first sample and can't be converted in the second sample? Does it matter if the size is known at compile time?

我认为在第二种情况下需要进行 2 次转换,编译器只能完成一次隐式转换.

I think there are 2 conversions needed in the second case, and only one implicit conversion can be done by compiler.

这段代码编译得很好:

void f(int&, char**&){}

int main()
{
    int argc = 2;
    char* temp[] = { "", "", nullptr };
    char** argv = temp;
    f(argc, argv);
    return 0;
}

推荐答案

Jefffrey 的评论 引用了标准,这里是:

Jefffrey's comment references the standard, here it is:

4.2 数组到指针的转换[conv.array]

4.2 Array-to-pointer conversion [conv.array]

可以转换类型为N T 数组"或T 未知边界数组"的左值或右值到指向 T 的指针"类型的纯右值.结果是一个指向数组的第一个元素.

An lvalue or rvalue of type "array of N T" or "array of unknown bound of T" can be converted to a prvalue of type "pointer to T". The result is a pointer to the first element of the array.

纯右值是:

纯右值(纯"右值)是标识临时值的表达式对象(或其子对象)或者是与任何不相关的值对象.

A prvalue ("pure" rvalue) is an expression that identifies a temporary object (or a subobject thereof) or is a value not associated with any object.

您不能将非常量引用绑定到临时引用.

You cannot bind a non-const reference to a temporary.

int& i = int(); // error

char* argv[] = { "", "", nullptr };
// the result of the conversion is a prvalue
char**& test = argv; // error

因此下面的代码会愉快地编译:

Therefore the following code will happily compile:

#include <iostream>

void f(int& argc, char** const& argv){
    std::cout << argv[0] << std::endl; // a
}

int main()
{
    int argc = 2;
    char* argv[] = { "a", "b", nullptr };
    f(argc, argv); 
    return 0;
}


Kanze's评论.

在 OP 中提供的第一个示例中,char* argv[]char** argv 是等效的.因此,没有转换.

In the first example provided in the OP, char* argv[] and char** argv are equivalent. Therefore, there is no conversion.

std::cout << std::is_array<decltype(argv)>::value << std::endl; // false
std::cout << std::is_array<char**>::value << std::endl; // false
std::cout << std::is_array<char*[]>::value << std::endl; // true
std::cout << std::is_same<decltype(argv), char**>::value << std::endl; // true
std::cout << std::is_same<decltype(argv), char*[]>::value << std::endl; // false

这篇关于C++ char*[] 到 char** 的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆