[英]compile time check template type C++
我正在嘗試檢查模板類型並適當調用一個函數。 但是,這似乎不起作用。 我嘗試使用is_same, C ++編譯時類型檢查 , 用於檢查類型相等的編譯時函數和boost :: is_same。 一切都給了我同樣的錯誤。 以下是示例代碼。
#include <iostream>
#include <type_traits>
using namespace std;
class Numeric
{
public :
bool isNumeric()
{
return true;
}
};
class String
{
};
template <class T>
class Myclass
{
private:
T temp;
public:
void checkNumeric()
{
if(std::is_same<T,Numeric>::value)
{
cout << "is numeric = " << temp.isNumeric();
}
else
{
cout << "is numeric = false" << endl;
}
}
};
int main()
{
Myclass<Numeric> a;
a.checkNumeric();
Myclass<String> b;
b.checkNumeric();
}
在編譯上面的代碼時,我收到以下錯誤。
make all
Building file: ../src/TestCPP.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/TestCPP.d" -MT"src/TestCPP.d" -o "src/TestCPP.o" "../src/TestCPP.cpp"
../src/TestCPP.cpp:36:36: error: no member named 'isNumeric' in 'String'
cout << "is numeric = " << temp.isNumeric();
~~~~ ^
../src/TestCPP.cpp:51:4: note: in instantiation of member function 'Myclass<String>::checkNumeric' requested here
b.checkNumeric();
^
1 error generated.
make: *** [src/TestCPP.o] Error 1
在這種情況下,我既沒有String或Numeric類。 它來自第三方圖書館。 我只實現了MyClass,它將被打包為另一個庫。 我希望使用MyClass的應用程序將傳遞給屬於第三方類的String或Numeric。 MyClass是一個專門的矩陣操作,Dense / Sparse矩陣是來自第三方庫的類數字和字符串類。 我想檢查使用我的庫和第三方庫的應用程序是否根據屬於第三方庫的類類型調用MyClass。
請告訴我如何解決這個問題。
不需要做任何花哨的事情; 這可以使用普通的模板專業化來處理。
template <class T>
class Myclass
{
private:
T temp;
public:
// called for general T
void checkNumeric() {
cout << "is numeric = false" << endl;
}
};
// specialized version for T = Numeric
template<> void Myclass<Numeric>::checkNumeric() {
cout << "is numeric = " << temp.isNumeric() << endl;
}
您需要在編譯期間選擇啟用/禁用功能,而不是在運行時選擇。 我建議做類似的事情( ideone.com上的代碼 ):
#include <iostream>
#include <type_traits>
class Numeric {
public:
bool isNumeric() {
return true;
}
};
class String {
};
template<class T>
class Myclass {
private:
T temp;
public:
template<typename U = T, typename std::enable_if<std::is_same<U, Numeric>::value, std::size_t>::type = 0>
void checkNumeric() {
std::cout << "is numeric = " << temp.isNumeric() << std::endl;
}
template<typename U = T, typename std::enable_if<!std::is_same<U, Numeric>::value, std::size_t>::type = 0>
void checkNumeric() {
std::cout << "is numeric = false" << std::endl;
}
};
int main() {
Myclass<Numeric> a;
a.checkNumeric();
Myclass<String> b;
b.checkNumeric();
}
節目輸出:
is numeric = 1
is numeric = false
希望這可以幫助。
if else
將強制編譯器實例化兩個控制流。 由於存在T
不是Numeric
類型的情況(即使代碼可能不通過該路徑),這將導致編譯錯誤。 你需要的是一個編譯時控制流程,在if_then_else
行中
template<int condition, int true_val, int false_val>
struct if_then_else {
enum { val = true_val };
};
template<int true_val, int false_val>
struct if_then_else<false, true_val, false_val> {
enum { val = false_val };
};
然后if_then_else< std::is_same<T, Numeric>::value, 1, 0>::value
將為Numeric
類型賦予1(true),為非數字類型賦予0(false),而無需無效地實例化非數字。
MyClass<T>::checkNumeric()
調用T::isNumeric()
。 您的String
類沒有這樣的函數,因此MyClass<String>::checkNumeric()
不會編譯。
選項:
String::isNumeric()
。 std::is_same
得到你的答案了,那么為什么要調用std::is_same
isNumeric()
呢? 有兩種方法可以解決這個問題。
addNumeric()
添加到String
。 如果您有權修改String
這是最簡單的解決方案。 String
,則可以使用幫助程序類來幫助完成該過程。 這是輔助類。
template <typename T1> struct IsNumeric
{
static bool get(T1 const& temp)
{
return false;
}
};
template <> struct IsNumeric<Numeric>
{
static bool get(Numeric const& temp)
{
return temp.isNumeric();
}
};
這是你的主要課程:
template <class T>
class Myclass
{
private:
T temp;
public:
void checkNumeric()
{
std::cout << " is numeric = " << IsNumeric<T>::get(temp) << std::endl;
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.