1

std::vectorから派生した次のクラスBがあります

class B: public std::vector <unsigned int>
{
    public:
            B() : std::vector <unsigned int> ( 0 ) {}
};

そして次のように書かれたクラスA:

class A
{
    private:        
            B b;    
    double x;

public:
    B & getB () {return b;}
    B const & getB() const {return b;}

    bool operator() ( const A & a ) const
            {
                    return a < a.x;
            }
};

std :: listに格納されているオブジェクトAの変数bへの参照をそのイテレータから返すことができないのはなぜですか(そしてその方法)?

int main ()
{
std::set <A > alist;
std::set <A> ::iterator i_alist = alist.begin();

for (; i_alist != alist.end(); i_list++)
{
    B &il = (*i_alist).getB(); //Compiler error
    B &il2 = i_alist->getB(); //Compiler error

    il.push_back(10);   //Modify il and concurrently B
}
} 

コンパイラエラー:

Error   1   error C2440: 'initializing' : cannot convert from 'const B' to 'B &'    d:\test.cpp

ご協力いただきありがとうございます...

質問の編集

const_castを使用した可能な解決策:

B &il2 = const_cast <B&> ( i_alist->getB() );
4

2 に答える 2

7

これはほとんど関係がなくstd::vector、すべてがと関係がありstd::setます。オブジェクトをに保存しますstd::set。の要素はstd::set外部から変更できません。セットに要素を挿入すると、それを変更することはできません。

このため、std::set::iterator定数オブジェクトでなくても、定数オブジェクトに評価される可能性があります(そして評価されます)const_iterator(言語仕様では、実際には同じ型を参照できますがstd::set::iteratorstd::set::const_iterator必須ではありません)。つまり、あなたの例*i_listでは、タイプがconstで修飾されたオブジェクトですconst A。コンパイラは、のconstバージョンを呼び出します。getBこれは、を返しますconst B &。の非定数バージョンが呼び出されることを期待して、その定数を突破することを望んでいるgetBようです。

ある種のハック(const_castなど)を使用してset要素からconstnessを削除し、コンパイラーに非constバージョンのを呼び出させる場合を除いて、これを回避する方法はありませんgetB

const_castベースのハックソリューションは次のようになります

B &il = const_cast<A &>(*i_alist).getB();

Bまたは、返された参照から後でconstnessを削除できます

B &il = const_cast<B &>((*i_alist).getB());
B &il2 = const_cast<B &>(i_alist->getB());
于 2012-12-03T16:39:01.737 に答える
0

あなたの例について奇妙に見えることがいくつかあります:

  1. から派生しないでくださいstd::vector。その用途向けには設計されていません。そして、怠惰を除いて、つまりタイピングを避けるために、通常そうする理由はありません。
  2. それは何A::operator()のためですか?使用しているコンパレータを提供するための奇妙な方法のように見えstd::setます。std::set通常、クラスをどこかに詰め込んだからといって、クラスを変更することはありません。本当にAを比較できるようにしたい場合は(通常、セットだけでなく)、適切な無料を作成しbool operator<(A const&, A const&);ます。セットのみの場合は、セットを使用する場所にカスタムコンパレータを作成します。(そのコンパレータはAのプライベートにアクセスする必要はありません)
  3. 何にA::x使われますか?比較のためだけですか、それともセット内の比較のためだけですか?それだけの場合は、xをキーとして、実際のオブジェクトを値として配置する場所、std::map<double, A>またはaを使用することを検討してください。std::map<double, B>

ほら、私が尋ねる多くの未解決の質問があります、そして多分(地図を使った)解決策はあなたの問題にさえ適合しません。これは、実際のコードを表示せず、意味のない名前の例のみを表示したためです。したがって、コードで実際に達成したいことではなく、あなたがやろうとしていることだけがわかります。

PS:そもそも注文されたコンテナさえ必要ないかもしれません、それはすべてのオブジェクトをに詰め込んでからそれで十分かもしれませstd::vectorstd::sort。実際に持っているオブジェクトの種類(例のAはコピー/スワップが安価です)およびコンテナーの使用方法(挿入がループとインターリーブされる方法など)によって異なります。

于 2012-12-03T17:01:47.917 に答える