23

同様の質問: constexpr ではなく、特殊なテンプレート構造体で実装されるのはなぜですか? type_traits–しかし、別の答えがあります。

エイリアス テンプレートは特殊化できないため、現在、型特性を直接実装するために使用できないことを認識しています1。ただし、これは委員会の意識的な決定であり、私が見る限り、これを禁止する技術的な理由はありません。

では、型特性をエイリアス テンプレートとして実装し、構文を簡素化する方が理にかなっているのではないでしょうか?

検討

 typename enable_if<is_pointer<T>::value, size_t>::type
 address(T p);

 enable_if<is_pointer<T>, size_t> address(T p);

もちろん、これによりBoost.TypeTraitsから移行する際にインターフェースの破壊的な変更が発生しますが、これは本当に大きな問題なのでしょうか?

結局のところ、型が異なる名前空間に存在するため、コードを変更する必要があり、多くの現代の C++ プログラマーは名前空間を開くことに消極的であるため、明示的に修飾されます (変更される場合)。

一方で、コードは大幅に簡素化されます。また、テンプレートのメタプログラミングがしばしば深くネストされ、複雑で複雑になることを考えると、より明確なインターフェイスが有益であることは明らかです。

何か不足していますか?そうでない場合は、単なる当て推量ではなく、委員会の決定の根拠に関する知識に基づいた (そして引用できる) 回答をいただければ幸いです。


1しかし、間接的には非常にうまくいっています! 検討:

template <typename T> using is_pointer = typename meta::is_pointer<T>::type;

現在のタイプmeta::is_pointer<T>に対応する場所。std::is_pointer<T>

4

3 に答える 3

16

あなたの質問に対する最も具体的な答えは次のとおりです。誰もそのようにすることを提案したことはありません。

C ++標準委員会は、多国籍、複数の企業によるボランティアの集まりです。あなたはそれを単一の組織内の設計委員会として考えています。C ++標準委員会は、文字通り、標準草案に言葉を入れるという提案なしには何もできません。

提案がなかった理由は、型特性が初期の提案であり、ブーストの実装が2000年頃にさかのぼるからだと思います。また、テンプレートエイリアスの実装が遅れていました。委員会のメンバーの多くは、自分たちが実施していないことを提案することに消極的です。そして、あなたの提案を実行する機会はほとんどありませんでした。

C++11の出荷には多くのプレッシャーがありました。それは本当に2009年に出荷することを意図しており、その出荷日がずれたとき、すでに検討中の機能を修正する以外に、ワーキングペーパーに何かをすることは非常に困難でした。ある時点で、出荷しないように、バックバーナーに素晴らしい新しいアイデアを追加する必要があります。

アップデート

C ++ 14以降、TransformationTraits(型を生成するもの)にテンプレートエイリアススペルが追加されました。次に例を示します。

template <bool b, class T = void>
  using enable_if_t = typename enable_if<b,T>::type;

また、C ++ 1zの作業ドラフトには、値をもたらす特性のテンプレート変数スペルが含まれるようになりました。

template <class T>
  constexpr bool is_pointer_v = is_pointer<T>::value;

また、C ++ 11でも、次のことができます。

typename enable_if<is_pointer<T>{}, size_t>::type
address(T p);

{}つまり、代わりに使用できます::value(コンパイラがconstexprサポートしていると仮定します)。C ++ 14では、次のようになります。

enable_if_t<is_pointer<T>{}, size_t>
address(T p);

そしてC++1zでは:

enable_if_t<is_pointer_v<T>, size_t>
address(T p);

C++1zとC++14の違いはごくわずかであるため、文字を保存することすらできず、これら2つの文字を配置する場所を変更{}するだけであることに注意してください。_v

于 2012-02-29T14:53:08.640 に答える
2

<memory>およびを含む他のいくつかのライブラリと同様に、型特性は<functional>C++ TR1 から継承されました。これはあまり正式でないドキュメントでしたが、Boost よりも正式であり、互換性は価値があります。

また、型特性はすべて から派生していることに注意してください。これは への変換関数をstd::integral_constant<bool>実装しています。そのため、必要に応じて、少なくとも部品を節約できます。constexprbool::value

于 2012-02-29T14:54:38.583 に答える
1

エイリアスが次のような特性に役立つかどうかについて混乱があるように見えるため、完全な補足としてstd::is_pointer:

Boost.MPL ルートに進み、Boost.MPL スタイルの整数定数、つまり型を使用することを決定できます。

template<typename Cond, typename Then = void>
using enable_if = typename std::enable_if<Cond::value, Then>::type;

// usage:
template<
    typename T
    , typename = enable_if<std::is_pointer<T>>
>
size_t address(T p);

または、代わりに値を使用することもできます

template<bool Cond, typename Then>
using enable_if = typename std::enable_if<Cond, Then>::type;

// can use ::value
template<
    typename T
    , typename = enable_if<std::is_pointer<T>::value>>
>
size_t address(T p);

// or constexpr conversion operator
template<
    typename T
    , typename = enable_if<std::is_pointer<T> {}>
>
size_t address(T p);

後者の場合、 : を使用できないことに注意してくださいenable_if<std::is_pointer<T>()>:std::is_pointer<T>()は関数型 ( を取りvoid、 を返すstd::is_pointer<T>) であり、この場合、エイリアスは型ではなく値を取るため、無効です。中かっこは、代わりに定数式であることを保証します。

お気づきかもしれstd::is_pointerませんが、 はテンプレート エイリアスの恩恵をまったく受けません。::valueこれは、興味深い部分がではなくにアクセスしている特性であるため、驚くことではありません::type。テンプレート エイリアスは、メンバー型にのみ役立ちます。のtypeメンバーはstd::is_pointer、Boost.MPL スタイルの整数定数 (この場合はstd::true_typeまたはstd::false_type) であるため、興味深いものではないため、これは役に立ちません。ごめん!

于 2012-02-29T22:03:07.747 に答える