2016-10-01 5 views
4

私が書いたこのテンプレートを最適化するための慣用方法を探しています。他のパラメータに応じてテンプレートパラメータを計算する慣習的な方法

私の主な関心事は、テンプレートパラメータnを正しく定義し、それをリターンパラメータとして使用してユーザが上書きしないようにすることです。

このテンプレートを慣用的なC++の方法で書く方法については、他の提案もあります。

template< 
    typename InType=uint32_t, 
    typename OutType=float, 
    unsigned long bits=8, 
    unsigned long n=(sizeof(InType) * 8)/bits 
> 
std::array<OutType,n> hash_to_color(InType in) noexcept {  
    InType mask = ~0; 
    mask = mask << bits; 
    mask = ~mask; 
    std::array<OutType,n> out; 
    auto out_max = static_cast<OutType>((1 << bits) - 1); 
    for (auto i = 0; i < n; i++) { 
    auto selected = (in >> (i * bits)) & mask; 
    out[i] = static_cast<OutType>(selected)/out_max; 
    } 
    return out; 
} 
+0

をユーザーがそれを上書きしないようにしたい場合は、おそらくあなたは、単に 'それは正しい値だとstatic_assert'ことができますか? –

答えて

3

nテンプレートパラメータについて、あなたはC++ 14で戻り値の型としてautoを使用してそれを避けることができます。

template<int N> 
auto f() 
{ 
    constexpr int bar = N * 3; 
    std::array<int, bar> foo; 
    return foo; 
} 

もちろん、配列テンプレートパラメータの計算は定数式でなければなりません。

(C++ 11と互換性のある)別のオプションは、トレーリング戻り型である:

template<int N> 
auto f() -> std::array<int, N * 3> 
{ 

これはほんの少しより詳細からC++ 14の可能戻り型推論のを利用してよりreturn声明。

注:コード内の~00intなので間違っています。それは~(InType)0である必要があります。また、(1 << bits) - 1には潜在的なオーバーフローの問題があります。

+0

ありがとうございます。それは役に立ちます。私はビットが 'static_assert(bits somnium

2

私はM.Mの答えが優れていると思います。あなたのケースでは、そこに示唆されている2つの選択肢の1つを間違いなく使用しています。

は、N与えられ、後でロジックがあるような状況が発生したと仮定していない3 Nが、より複雑なもの、例えば、nは + 3のn + 1を使用しています。あるいは、ロジックがそれほど複雑ではないかもしれませんが、変更される可能性があります。

(ただ、私はこれらがあなたの質問やMMの答えの文脈における重大な問題があるとは思わない、再び明確にする。)

ので、第三の選択肢が出て考慮することですconstexpr機能へのロジック:

template<int N> 
std::array<int, arr_size(N)> f() { 
    return std::array<int, arr_size(N)>(); 
} 
:それは constexprなので

#include <array> 

constexpr int arr_size(int n) { return n * n + 3 * n + 1; } 

は、テンプレートをインスタンス化するために使用することができます

この関数には明示的な戻り値の型がありますが、論理はarr_sizeに1回しか表示されません。

あなたはいつものようにこれを使用することができます:

int main() { 
    auto a = f<10>(); 
    a[0] = 3; 
} 
関連する問題