乗算

2016-10-12 18 views
4

私は次のような問題があります:あなたが上見ることができるように乗算

template< size_t... N_i > 
class A 
{ 
    // ... 
    std::array< float, /* product of the unpacked elements of N_i */ > arr; 
}; 

を、私はクラスAのメンバーとしてarrという名前std::arrayを宣言してみてください。ここでは、arrのサイズをN_iとしたいとします。たとえば、A<2,3,4>の場合、「arr」のサイズは2*3*4=24である必要があります。
これはどのように実装できますか?

あなたがこれを行うことができますC++ 14では

答えて

11

:C++ 14では

std::array < float, (... * N_i)> arr; 

C++ 11では
// outside the class 
template<size_t... Ns> 
constexpr size_t product(){ 
    size_t p = 1; 
    for(auto n : { Ns... }) p *= n; 
    return p; 
} 

// then 
std::array< float, product<N_i...>()> arr; 

また
template<size_t... N_i> 
struct product { 
    static const size_t value = 1; 
}; 

template<size_t N_1, size_t... N_i> 
struct product<N_1, N_i...> { 
    static const size_t value = N_1 * product<N_i...>::value; 
}; 

std::array< float, product<N_i...>::value> arr; 

、あなたは再帰を使用することができますconstexpr機能。

template<typename ...Args> 
constexpr int multiply(Args&&... args) 
{ 
    return (args * ...); 
} 

それはC++ 17倍の式を使用し、の再帰的定義を行うことができます

template< size_t... N_i > 
class A 
{ 
    // ... 
    std::array< float, multiply(N_i ...) > arr; 
}; 
+2

...ここでは、上の答えで 'C++ 'の進化を見ることができます。 – bolov

3

:それは次のようにあなたのクラスが定義することができます

#include<cstddef> 

template<std::size_t... I> 
constexpr auto f() { 
    std::size_t v = 1; 
    std::size_t _[] = { (v = v*I)... }; 
    (void)_; // silent a warning and nothing more 
    return v; 
} 

int main() { 
    static_assert(f<2,3,4>() == 24,"!"); 
} 

template< size_t... N_i > 
class A { 
    // ... 
    std::array< float, f<N_i...>()> arr; 
}; 
最小限、実施例として

size_t v = 1; 
size_t _[] = { (v = v*N_i)... }; 

C++では17 fold-expressionsが簡素化されます。 C++ 17では

+0

C++ 11 'constexpr'のでは動作しません:クリーンな外観を持つことができますvariable templateこれを使用して

とC++ 14で

。 –

+0

@ T.C。あなたは正しい、彼らは_relaxed_ではなかった。ありがとう。 – skypjack

1

あなたは、配列の宣言でこの機能を使用することができますconstexpr関数。

template <typename ...Ts> 
constexpr size_t product() 
{ 
    return 1; 
} 
template <size_t I,size_t... Is> 
constexpr size_t product() 
{ 
    return I * product<Is...>(); 
} 

template <size_t I, size_t... Is> 
constexpr size_t prod = product<I, Is...>(); 


template< size_t... N_i > 
class A 
{ 
    std::array< float, prod<N_i...> > arr; 
}; 
+2

...あなたがそれを持っている場合は、折り畳み式を差し込んでください。なぜ特別な機能ですか? –

+0

確かに、これははるかに短いです...約95%:-)それでも、私は理解して拡張する方が*少し良いと感じています。 – davidhigh

1

このように含めることができます。