Stroustroupの本「C++プログラミング第4版」を検討しています。そして私は彼の例をマトリックスデザインに従おうとしています。複雑なタイプ名パラメータを持つテンプレート関数を理解する助けが必要です
彼のマトリックスクラスはテンプレートに大きく依存しており、私はそれらを理解するために最善を尽くしています。 ここ
は私の質問の主題を構築する線です:それは一般のスライスのアイデア (§40.5.6)を使用していますEnable_ifとAll()がどのように実装されているのかを説明しています。A Matrix_slice要素の位置に添字の セットをマッピングマトリックスの実装の一部であるこのマトリックスのヘルパークラスの一つです。以前の本の中で
template<typename... Dims, typename = Enable_if<All(Convertible<Dims,size_t>()...)>> size_t operator()(Dims... dims) const; // calculate index from a set of subscripts
:ここ
template<size_t N> struct Matrix_slice { Matrix_slice() = default; // an empty matrix: no elements Matrix_slice(size_t s, initializer_list<size_t> exts); // extents Matrix_slice(size_t s, initializer_list<size_t> exts, initializer_list<siz e_t> strs);// extents and strides template<typename... Dims> // N extents Matrix_slice(Dims... dims); template<typename... Dims, typename = Enable_if<All(Convertible<Dims,size_t>()...)>> size_t operator()(Dims... dims) const; // calculate index from a set of subscripts size_t size; // total number of elements size_t start; // star ting offset array<size_t,N> extents; // number of elements in each dimension array<size_t,N> strides; // offsets between elements in each dimension }; I
template<bool B,typename T>
using Enable_if = typename std::enable_if<B, T>::type;
constexpr bool All(){
return true;
}
template<typename...Args>
constexpr bool All(bool b, Args... args)
{
return b && All(args...);
}
彼らはすでに仕事と彼のEnable_ifの実装を見て、私もコンバーチブルの機能を推定する方法を理解するための形成:
template<typename From,typename To>
bool Convertible(){
//I think that it looks like that, but I haven't found
//this one in the book, so I might be wrong
return std::is_convertible<From, To>::value;
}
だから、私はこのテンプレート関数宣言 のビルディングブロックをundersandことができますが、しようとしたとき、私は混乱しています彼らがどのようにaltogatherを働かせるか理解する。 私はあなたが私たちが最後にものを手に入れるんので、
template<typename... Dims,
//so here we accept the fact that we can have multiple arguments like (1,2,3,4)
typename = Enable_if<All(Convertible<Dims,size_t>()...)>>
//Evaluating and expanding from inside out my guess will be
//for example if Dims = 1,2,3,4,5
//Convertible<Dims,size_t>()... = Convertible<1,2,3,4,5,size_t>() =
//= Convertible<typeof(1),size_t>(),Convertible<typeof(2),size_t>(),Convertible<typeof(3),size_t>(),...
//= true,true,true,true,true
//All() is thus expanded to All(true,true,true,true,true)
//=true;
//Enable_if<true>
//here is point of confusion. Enable_if takes two tamplate arguments,
//Enable_if<bool B,typename T>
//but here it only takes bool
//typename = Enable_if(...) this one is also confusing
size_t operator()(Dims... dims) const; // calculate index from a set of subscripts
を助けることができることを願っていますか? この構築
template<typename ...Dims,typename = Enable_if<true>>
size_t operator()(Dims... dims) const;
質問は以下のとおりです。
- は、我々は
- はなぜ我々は型名
- のために( '=')が割り当てられていないEnable_ifための第二のテンプレート引数を必要としないでください私たちは最終的に何を得ますか?
更新: あなたはstd::enable_if
がそのテンプレートで、私はここに The C++ Programming Language 4th editionページ841で参照するよ同じ本(マトリックスデザイン)
これは実際のコードにすることはできません。 'Enable_if()...)>'は、テンプレート引数がコンパイル時に知られている式でしかないので、コンパイラエラーを引き起こします。 'All'の戻り値は返しません。 –
SergeyA
@SergeyA彼は関数定義の前に 'constexpr'が足りないと思う。私はそれがうまくいくと確信しています。 – SirGuy
@GuyGreer、OPかもしれません。しかしOP以外は何が欠けているのですか? ;) – SergeyA