0

私は c++ テンプレートが初めてです。2 つの異なるテンプレート クラスを操作できる一連の関数を作成しています。1 つは常に値で渡す必要があり、もう 1 つは膨大な量のデータを表すため、参照で渡す必要があります。

簡単な例を次に示します。arg に ref 型のタグが付けられている場合、関数シグネチャを const ref で取得するものとして定義する必要があります。

template<bool B, typename, typename T2>
struct if_ {};

template<typename T1, typename T2>
struct if_<true, T1, T2> {
    typedef T1 type;
};

template<typename T1, typename T2>
struct if_<false, T1, T2> {
    typedef T2 type;
};

struct ByvalTypeTag {};
template<typename T>
class Byval : public ByvalTypeTag 
{
    T somedata;
};

struct ByrefTypeTag {};
template<typename T>
class Byref : public ByrefTypeTag
{
    T somedata;
};

template<typename T>
void myfunc(typename if_<std::is_base_of<ByrefTypeTag, T>::value, const T&, T>::type arg)
{

}

int _tmain(int argc, _TCHAR* argv[])
{
    Byref<int> arg;
    myfunc( arg );
    return 0;
}

私が得るエラーは次のとおりです。

エラー C2783: 'void myfunc(if_::value,const T&,T>::type)': 'T' のテンプレート引数を推測できませんでした

たぶん、これは間違った方法です。可能であれば、同じ機能のために書いている比較的重複したテンプレートの数を削減しようとしています。

4

3 に答える 3

1

ええ、コンパイラは型を推測できません。自分で T を指定する必要があります。

myfunc<ByRef<int>>(arg);

または、より一般的なタグ ディスパッチ システムを使用することもできます。

class byref
{
    typedef byref_tag tag;
    ...
};

template < typename T >
void fun(T const& t, byref_tag) { ... }

template < typename T >
void fun(T t, byval_tag) { ... }

template < typename T >
void fun(T const& t)
{
    typedef typename T::tag tag;
    fun(t,tag());
}

さらに別の代替手段には、ラッパー関数とクラス テンプレートが含まれます。いずれにせよ、外側の関数は ref でなければなりません。

于 2013-03-15T23:34:06.287 に答える
1

非推定コンテキストTからタイプを推定しようとしています。

パラメーターの依存型に二重コロンが存在すると、通常、そのパラメーターの型を推測できないというヒントが得られます (同じ関数呼び出しで他の推測されたコンテキストが役立つ場合を除きますが、ここでは 1 つしかありません)。口論)。

C++11標準のパラグラフ14.8.2.5/5から:

非推定コンテキストは次のとおりです。

— 修飾 ID を使用して指定されたタイプのネストされた名前指定子。

[...]

具体的な例が必要な場合は、StackOverflow に関するこの Q&A が非常に適切です。この場合、型引数を明示的に指定できます。

myfunc<Byref<int>>(arg);

または、この 2 番目の Q&Aで提案されている 2 つの回避策のいずれかを選択することもできます。

于 2013-03-15T23:34:56.490 に答える
0

この実装でパラメーターを転送できます。

template<typename T>
void myfunc_impl(T arg)
{
    // Do the work here.
}

template<typename T>
void myfunc(const T &arg, typename std::enable_if<std::is_base_of<ByrefTypeTag, T>::value>::type* = 0)
{
  myfunc_impl<const T&>( arg ); // Pass a const ref
}

template<typename T>
void myfunc(const T &arg, typename std::enable_if<std::is_base_of<ByvalTypeTag, T>::value>::type* = 0)
{
  myfunc_impl<T>( arg );        // Pass a copy
}
于 2013-03-15T23:48:21.460 に答える