[英]Resolve self-referencing of nested initializer list datastructures
我正在嘗試解決這個難題:我正在使用可能包含原始類型的變體val
以及可能再次包含變體的用戶定義容器。 如果沒有盒子包裝對象,這種自引用數據結構是不可能的。 這個包裝器對象包裝了容器array
和obj
並提供了可確定的內存布局,因為它只持有指向這些容器的指針,而不是容器本身。
但現在問題來了:要使大括號括起來的初始化器列表語法與container
一起使用,box 數據結構需要為一系列keyval
和val
提供給定的 std::initializer_list-constructors。 但是要定義 val 我需要知道所涉及的所有模板參數的完整類型,包括 box 對象。 但這又需要知道 val。 這將創建一個互惠定義集。 我該如何解決?
代碼( 編譯器資源管理器):
#include <string>
#include <variant>
#include <type_traits>
struct array;
struct obj;
struct keyval;
template <typename T>
struct box
{
box(std::initializer_list<keyval> init) {
}
box(std::initializer_list<val> init) {
}
T* ptr_;
};
using val = std::variant<std::monostate, box<array>, box<obj>, int, bool>;
struct obj
{
obj() {
}
obj(std::initializer_list<keyval> init) {
}
};
struct array
{
array() {
}
array(std::initializer_list<val> init) {
}
};
struct keyval
{
keyval() {
}
keyval(std::string str, val a) : key_{str}, val_{a} {
}
std::string key_;
val val_ = std::monostate{};
};
struct container : public array, public obj
{
using array::array;
using obj::obj;
};
int main()
{
container some_container = { {"first", true }, { "second", 1 }, { "third", {{"2first", 2}, {"2second", true}} } };
}
錯誤:
<source>:15:31: error: 'val' was not declared in this scope
15 | box(std::initializer_list<val> init) {
| ^~~
<source>:15:34: error: template argument 1 is invalid
15 | box(std::initializer_list<val> init) {
| ^
<source>: In function 'int main()':
<source>:59:117: error: could not convert '{{"first", true}, {"second", 1}, {"third", {{"2first", 2}, {"2second", true}}}}' from '<brace-enclosed initializer list>' to 'container'
59 | container some_container = { {"first", true }, { "second", 1 }, { "third", {{"2first", 2}, {"2second", true}} } };
| ^
| |
|
struct box
的定義之前聲明using
指令。 由於在val
的聲明中引用了box
,因此您必須提出box
的前向聲明。template <typename T>
struct box;
using val = std::variant<std::monostate, box<array>, box<obj>, int, bool>;
template <typename T>
struct box {};
std::variant
不能直接從std::initializer_list
),這意味着box<array> b{{"2first", 2},{"2second", true}}; // OK
val v1{b}; // OK
val v2{{"2first", 2},{"2second", true}}; // ERROR
這就是container
構建失敗的原因。
一種簡單的解決方案是顯式提供類型。
container some_container = { {"first", true }, { "second", 1 }, { "third", box<array>{{"2first", 2}, {"2second", true}} } }; // note the box<array>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.