2016-04-22 8 views
2

関数の引数の数を取得する方法がC++ 11にあるかどうか疑問に思っていますか?関数のパラメータ数を取得する

は、例えば機能fooのために私はargCountは事前に3

#include <iostream> 
void foo(int a, int b, int c) 
{ 

} 
int main() 
{ 
    size_t argCount=MAGIC(foo); 
    return 0; 
} 

感謝したいです。

+0

どのような目的に適していますか? –

+1

@πάνταῥεῖ、重いメタプログラミングでこれを少なくとも1つのアプリケーションで知っています – SergeyA

+5

引数の数が異なる複数のオーバーロードがある場合、返されるMAGICとは何ですか? –

答えて

2

あなたは可変引数関数テンプレートを使用して、その情報を得ることができます。

#include <iostream> 

template <typename R, typename ... Types> constexpr size_t getArgumentCount(R(*f)(Types ...)) 
{ 
    return sizeof...(Types); 
} 

//----------------------------------  
// Test it out with a few functions. 
//----------------------------------  

void foo(int a, int b, int c) 
{ 
} 

int bar() 
{ 
    return 0; 
} 

int baz(double) 
{ 
    return 0; 
} 

int main() 
{ 
    std::cout << getArgumentCount(foo) << std::endl; 
    std::cout << getArgumentCount(bar) << std::endl; 
    std::cout << getArgumentCount(baz) << std::endl; 
    return 0; 
} 

出力:

3 
0 
1 

はそれがhttp://ideone.com/oqF8E8で働いて参照してください。 、あなたが使用して引数の数を取得することができます。これにより

template <typename R, typename ... Types> 
constexpr std::integral_constant<unsigned, sizeof ...(Types)> getArgumentCount(R(*f)(Types ...)) 
{ 
    return std::integral_constant<unsigned, sizeof ...(Types)>{}; 
} 

を更新

バリーの使用を示唆し

// Guaranteed to be evaluated at compile time 
size_t count = decltype(getArgumentCount(foo))::value; 

または

// Most likely evaluated at compile time 
size_t count = getArgumentCount(foo).value; 
+0

あまりにも複雑です:)短絡の例の私の答えを参照してください。 – SergeyA

+0

@ SergeyA、おかげです。それは今あなたの答えよりも単純化されました:) –

+0

とても大変です! :)唯一のことは、私の場合はあなたが機能している間は、関数を呼び出さないということです。あなたはあなたのconstexprを作る必要がありますが、これは決してそれが呼び出されないことを保証するものではありません - これが私のバージョンを好む理由です。しかし、あなたのコードは単純です。 – SergeyA

5

これはいくつかの理由で実際には意味をなさない。

これは本当に良いでしょうか?何らかのリフレクションを探しているかもしれませんが、それは(まだ)C++には存在しません。これは意味がありません

主な理由は、しかし、過負荷セットです:

void f(int); 
void f(int, int); 
std::cout << MAGIC(f); // what should this print?? 
+0

これを行う方法があります。 – SergeyA

+0

あなたがそれを行うことができるという事実は意味があるわけではありません。しかし、はい、あなたは正しいです。 – Ven

+1

これは、テンプレートメタプログラミングの多くのアプリケーションで完璧なものです。 – SergeyA

7

はい、簡単に行うことができます:

#include <cstddef> 
#include <iostream> 

template <class R, class... ARGS> 
struct function_ripper { 
    static constexpr size_t n_args = sizeof...(ARGS); 
}; 


template <class R, class... ARGS> 
auto constexpr make_ripper(R (ARGS...)) { 
    return function_ripper<R, ARGS...>(); 
} 

void foo(int, double, const char*); 

void check_args() { 
    constexpr size_t foo_args = decltype(make_ripper(foo))::n_args; 

    std::cout << "Foo has " << foo_args << " arguments.\n"; 
} 
関連する問題