[英]compile time check template type C++
I am trying to check a template type and appropriate invoke a function. 我正在尝试检查模板类型并适当调用一个函数。 However, this doesn't seem to work.
但是,这似乎不起作用。 I tried with is_same, C++ compile-time type checking , compile-time function for checking type equality and the boost::is_same.
我尝试使用is_same, C ++编译时类型检查 , 用于检查类型相等的编译时函数和boost :: is_same。 Everything is giving me the same error.
一切都给了我同样的错误。 The following is a sample code.
以下是示例代码。
#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();
}
While compiling the above code, I am getting the following error. 在编译上面的代码时,我收到以下错误。
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
In this case, I neither have String or Numeric class. 在这种情况下,我既没有String或Numeric类。 It comes out of a third party library.
它来自第三方图书馆。 I implement only MyClass which will be packaged as another library.
我只实现了MyClass,它将被打包为另一个库。 I expect the application that uses MyClass will either pass me a String or Numeric which belongs to a third party class.
我希望使用MyClass的应用程序将传递给属于第三方类的String或Numeric。 MyClass is a specialized matrix operation and Dense/Sparse matrix are the Numeric and String like classes that comes from a third party library.
MyClass是一个专门的矩阵操作,Dense / Sparse矩阵是来自第三方库的类数字和字符串类。 I want to check if the application that uses my library and the third party library is invoking MyClass based on the class type that belongs to the third party library.
我想检查使用我的库和第三方库的应用程序是否根据属于第三方库的类类型调用MyClass。
Kindly let me know how to fix this problem. 请告诉我如何解决这个问题。
No need to do anything fancy; 不需要做任何花哨的事情; this can be handled using ordinary template specialization.
这可以使用普通的模板专业化来处理。
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;
}
You need to select enable/disable functions during compilation, not during run-time. 您需要在编译期间选择启用/禁用功能,而不是在运行时选择。 I suggest doing something like that ( code on ideone.com ):
我建议做类似的事情( 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();
}
Program output: 节目输出:
is numeric = 1
is numeric = false
Hope this helps. 希望这可以帮助。
The if else
will force the compiler to instantiate both control flows. if else
将强制编译器实例化两个控制流。 Since there are cases where T
is not a Numeric
type (even though code may not run through that path), this wll cause a compile error. 由于存在
T
不是Numeric
类型的情况(即使代码可能不通过该路径),这将导致编译错误。 What you need is a compile time control flow, something in the lines of if_then_else
你需要的是一个编译时控制流程,在
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 };
};
Then if_then_else< std::is_same<T, Numeric>::value, 1, 0>::value
would give 1(true) for Numeric
types and 0(false) with non numeric ones without the need to invalidly instantiate the non numeric. 然后
if_then_else< std::is_same<T, Numeric>::value, 1, 0>::value
将为Numeric
类型赋予1(true),为非数字类型赋予0(false),而无需无效地实例化非数字。
MyClass<T>::checkNumeric()
calls T::isNumeric()
. MyClass<T>::checkNumeric()
调用T::isNumeric()
。 Your String
class does not have such a function, so MyClass<String>::checkNumeric()
does not compile. 您的
String
类没有这样的函数,因此MyClass<String>::checkNumeric()
不会编译。
options: 选项:
String::isNumeric()
. String::isNumeric()
。 std::is_same
, so why call isNumeric()
at all? std::is_same
得到你的答案了,那么为什么要调用std::is_same
isNumeric()
呢? There are two ways to solve this problem. 有两种方法可以解决这个问题。
addNumeric()
to String
. addNumeric()
添加到String
。 This is the easiest solution if you have permission to modify String
. String
这是最简单的解决方案。 String
, you can use a helper class to help with the process. String
,则可以使用帮助程序类来帮助完成该过程。 Here's the helper class. 这是辅助类。
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();
}
};
Here's your main class: 这是你的主要课程:
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.