簡體   English   中英

命名空間中的參數函數 (C++)

[英]Parametric function in namespaces (C++)

我需要定義 3 個具有相同目標但其行為基於 3 組常量值略有變化的函數; 換句話說,我可以簡單地編寫一個函數,通過將這些值作為輸入來在所有 3 種情況下執行此操作。 但是由於確實有很多常量(並且只有 3 個不同的集合),我肯定會避免這么長的函數聲明。 此外,我需要其他文件中的這些常量集進行相關計算。

我正在考慮使用命名空間,但我找不到任何適合我想要實現的東西。 只是為了讓事情更容易理解,這是我想要的一個例子(但顯然沒有編譯):

int parametric_function() {
    return a_constant + 1; //'a_constant' isn't defined yet
}

namespace first_behaviour {
    const int a_constant = 10;

    //make the function use the variable 'a_constant' defined here in some way
    int (*f)() = parametric_function;
}

namespace second_behaviour {
    const int a_constant = 20;

    //make the function use the variable 'a_constant' defined here in some way
    int (*f)() = parametric_function;
}

如您所見,我只需要編寫一次參數函數,就可以使用命名空間來獲取正確的函數和相關的常量集。 你對我可以嘗試做什么有什么建議嗎?

如果您只有一個變量,則可以直接將其作為模板參數傳遞,如this answer中所建議的那樣。

但是如果你有多個,你可以將它們包裝在一個結構中:

#include <iostream>

struct FirstBehavior
{
    static constexpr int a_constant = 10;
};
struct SecondBehavior
{
    static constexpr int a_constant = 10;
};

template <typename T>
int ParametricFunction()
{
    return T::a_constant + 1;
}

int main()
{
    std::cout << ParametricFunction<FirstBehavior>() << '\n'; // 1
}

在 c++ 中,您有模板:

template <int a_constant>
int parametric_function() {
    return a_constant + 1;
}

namespace first_behaviour {
    auto f = parametric_function<10>;
}

使用 HolyBlackCat 對結構和模板的建議,這將是一種方法。

該結構只是一個保存變量的包裝器。 在這個例子中,我把它變成了一個有狀態的變量(非常量),對於結構包裝器來說是靜態的。 它需要成為 parameteric_function 的預期名稱。

我認為使示例使用非常量變量可能更普遍適用於其他類型,例如std::stringstd::vector或您可能需要的任何東西。

extern int (*f)(); 只是為了消除編譯器警告。

#include <iostream>

using std::cout;

template <typename T>
int parametric_function() {
    ++T::a_variable;
    return T::a_variable;
}

namespace first_behaviour {
struct VarHolder {
    static inline int a_variable = 10;
};
extern int (*f)();
int (*f)() = &parametric_function<VarHolder>;
} // first_behaviour

namespace second_behaviour {
struct OtherVarHolder {
    static inline int a_variable = 20;
};
extern int (*f)();
int (*f)() = &parametric_function<OtherVarHolder>;
} // second_behaviour

int main() {
    int x = first_behaviour::f();
    int y = second_behaviour::f();
    cout << x << " " << y << "\n";
}

可能你可以用template做。 你可以:

template <int CONST_VAL>
int par_func();

template<>
int par_func<10>(){ return 4; }

template<>
int par_func<20>(){ return 1; }

template<>
int par_func<30>(){ return 9; }

然后,您可以根據需要將這些名稱別名為其他函數,或者您可以像這樣保留它們。 這也確保了只能使用專業化。

你也可以做你的例子:

template <int CONST_VAL>
int par_func(){
    return CONST_VAL + 1;
}

然后,您可以將其放入實現文件中,並僅顯式實例化您使用的那些,例如:

template int par_func<10>();

您可以以與命名空間模型相同的方式使用它,例如:

namespace func1 {
    int(* func)() = &par_func<10>;
}

namespace func2 {
    int(* func)() = &par_func<20>;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM