私は次のコードを持っています:
string join(initializer_list<string_view> strings);
initializer_list は std::initializer_list であり、string_view は std::string ビューではありませんが、const string& および const char* からのコンストラクターを持つ非常に類似したクラスです。
次に、次の呼び出しがありjoin
ます。
EXPECT_EQ("this", join({ string("this") }));
少し調査した結果、結果の初期化子リストの最初の要素が"this"
butではないことがわかりました"\0his"
。これは、によって作成されたテンポラリのデストラクタが、テンポラリの作成string("this")
直後に呼び出されるためですstring_view
(したがって、無効なポインタが含まれています)。の寿命がstring("this")
完全式の最後まで延長されないのはなぜEXPECT_EQ("this", join({ string("this") }));
ですか?
編集
わかりました、あなたが示唆したように、自己完結型の例があります:
#include <iostream>
#include <string>
using namespace std;
class string_view {
public:
string_view(const string& str)
: _begin(str.data())
, _end(str.data() + str.size()) {
std::cout << "string_view(...)" << std::endl;
}
const char* _begin;
const char* _end;
};
void join(initializer_list<string_view> strings) {
std::cout << "join(...)" << std::endl;
for (auto i = 0u; i < 5; ++i) {
std::cout << int(strings.begin()->_begin[i]) << " " << strings.begin()->_begin[i] << std::endl;
}
}
int main() {
join({ string("this") });
return 0;
}
最後の Visual Studio C++ (Express) でコンパイルされたこのプログラムの出力:
string_view(...)
join(...)
0
104 h
105 i
115 s
0
上記のプログラムはおそらく不正な形式であるため、コンパイラによって異なる場合があります。
デバッガーでの呼び出しの順序を調べたところ、次の順序があります。
main()
basic_string(const char*)
string_view(const string&)
~basic_string()
initializer_list(...)
join(...)
string("this")
のコンテンツを関数内で利用できるようにしたいと思いjoin
ます。`string("this") が前に破棄されるため、そうではありません。
関数がstring("this")
呼び出される前に一時文字列のデストラクタが呼び出されるのはなぜですか、つまり、完全な式の終わりまで延長されないのはなぜですか?join
string("this")
join({ string("this") })