R值引用默认参数临时,以容纳用于转换WSTRING的缓冲区?

问题描述 投票:0回答:0
。 我的代码处理来自不同来源的混合袋

std::string

std::wstring

,是的,我知道这远非理想,但让我们专注于技术。
问题
我想同时将

std::string

std::wstring
馈送到均匀的转换函数,我们称其为简化记录表达式的构造。
对于字符串,实现很简单:

tc_str(T StrT)

对于Wstring,我提出了以下在VS2022 AFAICT上使用的解决方案:

const char* tc_str(const std::string& str) { return str.c_str(); }

there是完整的

测试代码gist
.
用法摘要:
const char* tc_str(const std::wstring& wstr, std::string&& rTmpLifeExt = std::string()) {
    rTmpLifeExt = wchar_to_narrow(wstr);
    return rTmpLifeExt.c_str();
}

问题 是这个合法的C ++ 20?

aCcording至
Https://stackoverflow.com/a/12554621/321013

(ref

cppref
)(参考:
std::string narrow = ... std::wstring wide = ... printf("n: %s / w: %s", tc_str(narrow), tc_str(wide));

;§12.2 [class.temporary];

§1.9 [intro.execution]

)应该延长参考寿命“正确”,不应发生悬而未决的指针:

...

§12.2 [class.temporary]

的特殊情况 P4...临时性在另一点破坏的上下文[...]

P5...当引用与临时绑定时。 ...: 临时绑定到函数调用(5.2.2)中的参考参数(5.2.2),直到完整表达完成 包含呼叫

... in
§1.9 [intro.execution] p11

[

注:
...评估涉及的子表达

默认参数(8.3.6)被认为是在调用函数
的表达式中创建的,而不是定义的表达式 默认参数。

-末端注释

]

    我最大的疑问是在这里对R值与L值参考,但似乎他们受到了同样的对待。 caviven crably的登录API的约束,这是“足够好”的解决方案,还是有任何重大问题?
,我建议一个魔术较少的解决方案吗?

struct string_c_helper { std::string storage; char const* string_ptr = ""; operator char const*() const { return string_ptr; } bool uses_storage() const { return string_ptr == storage.c_str(); } string_c_helper() {} // empty string string_c_helper( char const* ptr ):string_ptr(ptr) {} string_c_helper( std::string const& str):string_ptr(str.c_str()) {} struct store_string_t {}; string_c_helper( store_string_t, std::string str ): storage(std::move(str)), string_ptr(storage.c_str()) {} // use storage for wstrings: string_c_helper( std::wstring const& wstr): string_c_helper(store_string_t{}, (wchar_to_narrow(wstr)) {} // allow move construction. If it uses storage, copy the // storage, otherwise just copy the pointer: string_c_helper(string_c_helper&& o): string_c_helper( o.uses_storage()? string_c_helper(store_string_t{}, std::move(o.storage)) : string_c_helper(o.string_ptr) ) {} string_c_helper(string_c_helper const&)=delete; string_c_helper& operator=(string_c_helper const&)& = delete; string_c_helper& operator=(string_c_helper&& o)& = delete; };

这种类型是一种

char const*
,并且可以选择携带它。 无论如何,它都可以隐式投放给

std::string。 它支持空字符串。 String_c_helpertc_str(const std :: wstring&wstr){ 返回WSTR; } String_c_helper tc_str(const std :: string&str){ 返回str; } 您可以将这些传递给C-API对象。 您甚至可以从功能中返回它们。 只有转换为Achar const*,有效性在全表达的末端结束。转换发生在。 基本上是您的,但是您的问题是解决为什么它的工作会使大多数C ++开发人员感到困惑。 因此,当它破裂时,他们几乎没有希望理解出了什么问题。 基本上,这基本上是“手动”进行字符串寿命扩展,而不是神奇地发生。

(旁边:由于保证的省略而不是无限递归。)

c++ language-lawyer c++20 rvalue-reference default-arguments
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.