聚合的结构必须知道聚合此结构的结构中的信息

时间:2016-03-12 14:46:10

标签: c++ c++11 vector stl

就像在std :: pair<中一样int,std :: vector> vector必须知道它的第一个元素对(即int)。

我遇到了以下有趣的问题。提供代码,请阅读评论。

codec => plain { charset => "ISO-8859-1" }
  • 可以在不手动向数据提供'my_holder_index'变量的情况下解决此任务(例如':my_data(my_data(my_holder_index))')。

  • std :: vector是否有可能在内存中找到DataHolder结构实例化的位置并尝试查找my_holder_index?

  • 有没有可能在没有点内存操作的情况下使用c ++ / STL实现这种行为? 感谢

1 个答案:

答案 0 :(得分:0)

由于您尚未解释问题中的任何内容与vector有什么关系(以及在vectorpair可以访问其他人的无意义声明pair)中的元素,我将专注于为您提供的实际代码找到解决方案。

问题2:

  

std :: vector是否有可能在内存中找到它实例化DataHolder结构的位置并尝试查找my_holder_index?

没有。在C ++中没有合法的方法(即:不调用UB),成员子对象可以访问其拥有对象中声明的变量。至少,不是没有将该变量传递给它。

哦,当然,您可以将this强制转换为unsigned char*,执行一些指针算法,然后将其强制转换为std::string。那可能&#34;工作&#34;对于某些实现。但它不是合法的C ++。如果没有其他原因,没有任何理由可以阻止您在提供Data成员的其他对象中的地方声明std::string。< / p>

问题1&amp; 3:

  

无需手动提供&my -holder_index&#39;即可解决此问题。变量到数据(例如&#39;:my_data(my_data(my_holder_index))&#39;)。

     

是否有可能在没有点内存操作的情况下使用c ++ / STL实现此行为?

执行您正在执行的操作的正确方法是使用CRTP。 Data应该是DataHolder的基类子对象(或者其他任何人可能想要使用它)。它将作为模板参数,从中派生出来的类。因此,它可以static_cast this指向派生类的指针。只要你总是将派生类作为模板参数传递,你就不会引发未定义的行为:

template<typename Derived>
  //Requires that `Derived` have a publicly accessible `my_holder_index` field
  //Which is something that has an `operator<<(ostream)` overload for it.
struct Data {
    DataType storage[5];
    void Show() {
        std::cout << "my_holder_index" << derived().my_holder_index;
        for(auto elem : storage) {
            std::cout << elem << " ";
        }
        std::cout << std::endl;
    }

private:
    Derived &derived() {return static_cast<Derived&>(*this);}
    const Derived &derived() const {return static_cast<const Derived&>(*this);}

};
struct DataHolder : Data<DataHolder> {
    std::string my_holder_index;
    DataHolder(std::string my_holder_index)
        : my_holder_index(my_holder_index) {}
    void Show() {
        // Do not show holder id here! It is the data that has to know it.
        Data<DataHolder>::Show();
    }
};