2015-12-05 8 views
7

のパラメータの種類を取得それでは、私たちは、次のコードを持っているとしましょう:は、パラメータパック

#include <stack> 

template<class... Args> 
auto make_stack(Args&&... args) 
{ 
    std::stack<INSERT_TYPE_HERE> s; 
    return s; 
} 

int main() 
{ 
    auto s = make_stack(1, 2.2, 3); //would be std::stack<double> 
    auto s2 = make_stack(1l, 2, 3); //would be std::stack<long> 
} 

私は、パラメータパック内の引数の一般的なタイプを見つけるだろうか?

+0

は残念ながら、保証は種類が同じであることはありません。 – skypjack

答えて

8

std::common_type<type_traits>から使用してください。これは、すべての型を変換できる共通の型を提供する型の特性です。だから、あなたが必要があると思い、あなたのケースで:

template<typename... Args> 
auto make_stack(Args&&... args) 
{ 
    using commonT = std::common_type_t<Args...>; 
    std::stack<commonT> s; 
    return s; 
} 

EDIT @DietmarKühlコメントで述べたように、あなたがC++ 11とではないC++ 14を使用する場合commonTstd::decayを使用することをお勧めします。これは、std::decayがC++ 14以降の結果の型にのみ適用されるようです。

+0

その簡単な例を教えてください。 – DeiDei

+0

@DeiDei In sec ...完了。 – vsoftco

+0

私は、 'std :: decay_t <....>'の結果を 'std :: common_type <...>'から得たいと思うかもしれません。もしすべての要素が左辺値ならば、 'std :: stack <...>'を作成しようとします。 –

0

残念ながら、タイプが同じであるという保証はありません。
あなたはstd::common_typeを使用していますが、(documentationから)があることに注意してくださいすることができます

は、すべての種類のT ...の間で共通の型を決定し、そのタイプのすべてのT ...暗黙的に変換することが可能です。

これは、それがあなたが期待するものではない可能性があることを意味します。

とにかく、あなたの例を見ると、あなたの問題は、以下のようなテンプレート関数とinitializer_listの使用によって簡単に解決できると私は思っています。
それは、実施例を次に示します。

#include <initializer_list> 
#include <stack> 

template<typename T> 
auto make_stack(std::initializer_list<T> list) 
{ 
    std::stack<T> s; 
    return s; 
} 

int main() 
{ 
    auto s = make_stack<double>({1, 2.2, 3}); //would be std::stack<double> 
    auto s2 = make_stack<long int>({1l, 2, 3}); //would be std::stack<long> 
}