具有該功能的定義:如何推導C++中的函數參數類型?
void f(int) { }
我想定義:
int a;
但如果函數定義更改爲:
void f(double) { }
變量定義必須成爲:
double a;
也就是說,「a」的類型必須與「f」函數的第一個參數相同。 我需要像下面這樣的東西:
decltype_of_argument<f, 0> a;
在C++中可能嗎?
具有該功能的定義:如何推導C++中的函數參數類型?
void f(int) { }
我想定義:
int a;
但如果函數定義更改爲:
void f(double) { }
變量定義必須成爲:
double a;
也就是說,「a」的類型必須與「f」函數的第一個參數相同。 我需要像下面這樣的東西:
decltype_of_argument<f, 0> a;
在C++中可能嗎?
如何使模板功能?
template <typename T>
void f(T t);
其中一種方法是使用typedef作爲函數參數的類型。例如
typedef int TParm;
void f(TParm);
TParm a;
您可以爲該類型選擇任何名稱。例如parm_t
等。重要的是不會有名稱衝突。
在這種情況下,如果要更改參數的類型,只需更改typedef。
或者,如果你的編譯器支持別名,你也可以寫
using TParm = int;
void f(TParm);
TParm a;
而且你可以用在命名空間或類中的函數。:)比如
struct IFunction
{
typedef int parm_t;
static void f(parm_t = parm_t()) {}
};
//...
IFunction::parm_t a;
IFunction::f(a);
這可能是最接近OP的要求,但我認爲這會更好地考慮這個需求......我的意思是double和int可以在需要時施放。 – Theolodis
這取決於你想要什麼在哪裏使用該變量。如果是在功能的模板可能是一個不錯的選擇:
template<typename T>
void foo(T) {
T a;
}
另外,如果你是功能之外,要真正知道這個要求,你可以使用Boost.TypeTraits,即function_traits<void (int)>::arg1_type
會給int
您可以通過模板元編程獲取類型:
template <class F> struct ArgType;
template <class R, class T>
struct ArgType<R(*)(T)> {
typedef T type;
};
void f(int) {}
#include <type_traits>
#include <iostream>
int main() {
// To prove
std::cout << std::is_same< ArgType<decltype(&f)>::type, int >::value << '\n';
// To use
ArgType<decltype(&f)>::type a;
}
根據你想使用它,你就需要專門這個豆蔻模板其他調用實體如成員福nunction poitner,具有更多參數的函數,函數等。在Boost庫中有更復雜的方法,參見例如。https://stackoverflow.com/a/15645459/1838266
注意:所有這些實用程序只在函數/可調用名稱明確映射到單個函數簽名時才起作用。如果一個函數被重載或者一個仿函數有多個operator()
,那麼必須通過明確地轉換成正確的簽名來挑選正確的函數/操作符,這使得通過模板找出部分簽名非常沒用。這適用於某種方式的模板爲好,雖然得到的簽名的明確secialized可調用的可能仍然是有用的,例如:
template <unsigned N, class F> struct ArgType; //somewhat more sophisitcated
template <class T> void f(int, T);
ArgType<0, decltype(&f<double>)> //int - ArgType has it's use here
ArgType<1, decltype(&f<double>)> //double - here it's useless...
+1優秀,這就是答案!我試圖寫這個,但你更快。 – deepmax
注意:如果'f'被重載,它將會是'ArgType
@ MatthieuM。感謝提示,galop1n和我對這個問題的評論提到了這個問題,爲了澄清答案,我添加了它。 –
decltype_of_argument是不可能的,在這裏解釋同樣的原因:HTTP://計算器.com/a/22631749/2694444 – galop1n
所以如果f需要一個獸人,你會想要一個獸人? – Theolodis
@ galop1n只適用於'f'被重載或函數重載'operator()' –