昨天我在課堂上詢問了模板顯式專業化。 鏈接。
現在我有同樣的目的,但現在我想使用繼承來避免代碼重復。如果我在基類中宣告一個函式,我就不能在派生類中宣告這個函式的特化。
我的代碼:
#include <stdexcept>
#include <iostream>
class Base
{
public:
template <typename T>
T fun()
{
throw std::runtime_error("Unsupported template param");
}
};
class Derived : public Base
{
};
template <>
bool Base::fun<bool>()
{
return true;
}
template <>
float Derived::fun<float>()
{
return 5.6f;
}
template <>
double Derived::fun<double>()
{
return 5.684;
}
int main()
{
Derived d;
bool d_b = d.fun<bool>();
float d_f = d.fun<float>();
double d_d = d.fun<double>();
char d_error = d.fun<char>();
}
VS 代碼錯誤:
不允許使用繼承的成員
加
錯誤:“float Derived :: fun ()”的模板 ID“fun”與任何模板宣告都不匹配
英特爾 C 編譯器:
source/app.cpp:25:16: error: no function template matches function template specialization 'fun'
float Derived::fun<float>()
^
source/app.cpp:30:1: error: extraneous 'template<>' in declaration of variable 'fun'
template <>
^~~~~~~~~~~
source/app.cpp:31:17: error: redefinition of 'fun' as different kind of symbol
double Derived::fun<double>()
^
source/app.cpp:25:16: note: previous definition is here
float Derived::fun<float>()
如果在 C 中這是不可能的,請回答另一個問題:在 C 中什么是廣為人知的實踐來做我想做的事。在我使用 D 語言并且一個人說我之前,我不會問自己“為什么”的問題。相反,我只是嘗試將 D 方法轉移到 C 。我同意。這就是我問的原因。
也許更好的方法是忽略模板并宣告分離的函式?例如:
- funToBool()
- funToFloat()
- funToDouble()
uj5u.com熱心網友回復:
如果您在 Derived 中添加 fun 的公共模板定義,這將編譯。
但這可能不會做你想要的。特別是d.fun<bool>();不會在 Base 中執行實作,而是在 Derived 中執行。
您不能專門化派生類中的模板函式。
你也不能在模板函式上使用子型別多型:模板不能是虛擬的。
您可以使用CRTP實作某種型別的靜態多型性。
是的,洗掉模板并使用分離的函式會起作用(a.toX()...)。
另一種選擇是使用多載(即傳遞虛擬引數或目標變數并撰寫不同的實作)。
根據要求添加虛擬引數解決方案的示例:
namespace TO {
static const bool BOOL = false;
static const double DOUBLE = 0.0;
static const int INT = 0;
}
struct A {
bool convert(bool dummy) {
return true;
}
};
struct B : public A {
using A::convert; // important
int convert(int dummy) {
return 2;
}
double convert(double dummy) {
return 3.0;
}
};
int main() {
B b;
std::cout << b.convert(TO::BOOL) << std::endl;
std::cout << b.convert(TO::DOUBLE) << std::endl;
std::cout << b.convert(TO::INT) << std::endl;
}
使用這種解決方案,在呼叫函式時存在隱式轉換的風險。toX() 可能是一個更安全的選擇。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/314643.html
