11

私はexplicitキャストオペレーターのための新しいもので遊んでいます。あなたが次のようなものを書く場合

struct Data {
    explicit operator string(); 
};

誤ってに変換することはできませDatastring。dargetデータ型boolは例外です。場合によっては、explicit-- contextualconversionとマークされていても暗黙的な変換が許可されます。if(...)したがって、次の例でこのデータ型を使用できます。

struct Ok {
    explicit operator bool(); // allowed in if(...) anyway
};

「25.4。(2)並べ替えと関連操作」の段落は、同様の標準的なコンテナCompareのファンクターにもこれを可能にするようです。しかし、gcc-4.7.0での試行は失敗し、それが私の誤解なのか、gccのバグなのかは確かですか?set

#include <set>

struct YesNo { // Return value type of Comperator
    int val_;
    explicit YesNo(int y) : val_{y} {}
    /* explicit */ operator bool() { return val_!=0; }
};

static const YesNo yes{1};
static const YesNo no{0};

struct LessYesNo {  // Comperator with special return values
    YesNo operator()(int a, int b) const {
        return a<b ? yes : no;
    }
};

int main() {
    std::set<int,LessYesNo> data {2,3,4,1,2};
}

例がコンパイルされるexplicit前に。operator bool()そして、「25.4。(2)」についての私の理解は、これも`explicitでコンパイルする必要があるということです。

変換setも機能するはずだというStdを正しく理解しましたか?explicit boolそして、これはgccのバグである可能性がありますか、それとも私は何か間違っていることを理解しましたか?

4

2 に答える 2

3

私の標準の解釈は少し異なります。セクション 25.4 は、ソートされたコンテナではなく、ソート アルゴリズムを扱っています。25.4.(1) で確立されたコンテキストは、25.4.(2) で指定された比較オブジェクトのプロパティが、ソートされたコンテナーではなく、25.4 のアルゴリズムに適用されることを意味します。

1 25.4 のすべての操作には 2 つのバージョンがあります。1 つは Compare 型の関数オブジェクトを使用するバージョンで、もう 1 つは演算子を使用するバージョンです。

2 Compare は関数オブジェクト型 (20.8) です。Compare 型のオブジェクトに適用された関数呼び出し演算の戻り値は、コンテキストに基づいて bool (4) に変換されると、呼び出しの最初の引数が 2 番目の引数より小さい場合は true になり、それ以外の場合は false になります。Compare comp は、順序関係を想定したアルゴリズム全体で使用されます。comp は、逆参照されたイテレータを介して非定数関数を適用しないと想定されています。

あなたの例がうまくいくかどうかはわかりませんが、セクション 25.4 はここでは当てはまらないと思います。

ベクトルと std::sort を使用した簡単なテストが機能します。

#include <list>
#include <algorithm>

struct YesNo { // Return value type of Comperator
    int val_;
    explicit YesNo(int y) : val_{y} {}
    explicit operator bool() { return val_!=0; }
};

static const YesNo yes{1};
static const YesNo no{0};

struct LessYesNo {  // Comperator with special return values
    YesNo operator()(int a, int b) const {
        return a<b ? yes : no;
    }
};

int main() {
    std::vector<int> data {2,3,4,1,2};
    std::sort(std::begin(data), std::end(data), LessYesNo());
}

編集:

連想コンテナの Compare パラメータは、セクション 25.4 で定義されています。

1 連想コンテナーは、キーに基づくデータの高速検索を提供します。このライブラリは、set、multiset、map、および multimap という 4 つの基本的な連想コンテナーを提供します。

2 各連想コンテナは、Key と、Key の要素に厳密で弱い順序付け (25.4) を誘導する順序付け関係 Compare でパラメータ化されます。さらに、map と multimap は、任意の型 T を Key に関連付けます。タイプ Compare のオブジェクトは、コンテナの比較オブジェクトと呼ばれます。

23. 私が見る限り、Compare の型に関する他の条件はありません。そのため、25.4 の制約を満たす型が等しく適用可能であると仮定することは合理的に思えます。

于 2011-11-04T19:22:10.090 に答える
2

セットに対しても明示的な bool 変換が機能するはずであるという Std を正しく理解しましたか?

これは、仕様のグレー エリアのようなものです。比較関数からの戻り値は、「bool に変換可能」である必要があります。しかし、それが何を意味するのかexplicit operator bool()は不明です。

たとえば、std::setの比較用法を次のように書くことができます。

CompFunc functor;
if(functor(input, currVal))
  ...

または、次のようにすることもできます。

CompFunc functor;
bool test = functor(input, currVal);
if(test)
  ...

これらは両方とも C++11 で技術的に合法ですか? わかりません。が の場合、明らかに 2 番目のものは失敗しoperator bool()ますexplicit

の定義を見たところ、もstd::shared_ptrありexplicit operator bool()ました。またstd::shared_ptr、セクション 20.7.2.2 のパラグラフ 2 で、「bool に変換可能」であると述べています。

したがって、2 番目のバージョンは次のように実装する必要があると推測しています。

CompFunc functor;
bool test = static_cast<bool>(functor(input, currVal));
if(test)
  ...

仕様のどこにも明示的に記載されていないという事実は、欠陥レポートとして提出する必要があることを意味します。しかし、おそらく GCC/libstdc++ のバグとして報告する必要もあります。

個人的には、安全のために、私はそれに頼りません。


コンテキスト変換について

セクション 4、パラグラフ 3 は次のように述べています。

そのような文脈で現れる式 e は、文脈上 bool に変換されると言われ、宣言が bool t(e); である場合にのみ整形式です。いくつかの発明された一時変数 t に対して、整形式です

したがって、「コンテキストでブール値に変換できる」操作は、それが機能することを意味しexplicit operator bool()ます。std::setの「比較」ファンクタは 25.4 の要件に該当する必要があり、これらの要件には「コンテキストに応じて bool に変換」が含まれているため、GCC/libstdc++ のバグのようです。

あなたがそれを助けることができるとき、私はまだそれを避けるだろう.

于 2011-11-04T19:11:25.613 に答える