3

次の 2 つのテンプレート関数を検討してください。

template<typename T>
void foo(T&& bar) {
    // do stuff with bar, which may or may not be an instance of a templated class
}

template<typename U, template<typename> class T>
void foo(T<U>&& bar) {
    // do stuff with bar, which must be an instance of a templated class
}

なぜ前者は (転送参照を使用して) 左辺値を受け入れ、後者は受け入れないのですか?


ID エイリアス テンプレートを転送参照にすることはできますか? これにも関連している可能性がありますが、参照の転送に関する制限の別の側面をカバーしているようです.

4

2 に答える 2

2

それが、言語が機能するべきだと標準が言っている方法だからです。

[14.8.2.1][temp.deduct.call] 3.
P が cv 修飾された型の場合、P の型の最上位の cv 修飾子は型推定のために無視されます。P が参照型の場合、P によって参照される型が型推定に使用されます。転送参照は、cv 修飾されていないテンプレート パラメーターへの右辺値参照です。P が転送参照で、引数が左辺値の場合、型推定のために A の代わりに「A への左辺値参照」型が使用されます。

この方法で左辺値参照として推定できるのは、CV 修飾されていないテンプレート パラメーターへの右辺値参照のみです。

やろうとしていることを達成するために、特性を使用してテンプレート テンプレート パラメーターを抽出できる場合があります。

#include <type_traits>

/***
 * Extract template from template type.
 */
template <typename I> struct get_template;

template <template<class> typename T, typename C>
struct get_template<T<C>> {
  template <typename U>
  using temp = T<U>;
};





template <typename T> struct A{};

struct B;

template<typename W>
void foo(W && bar) {
  typedef typename get_template<typename std::remove_reference<W>::type>::template temp<int> new_type;
  new_type my_variable;
}

int main() {
  A<B> temp;
  foo(temp);
}

または、 const & および && の関数を通常どおりオーバーロードします。

于 2016-02-27T06:37:47.540 に答える