简体   繁体   English

编译时检查模板类型C ++

[英]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: 选项:

  • Add and implement String::isNumeric() . 添加并实现String::isNumeric()
  • you're already getting your answer from std::is_same , so why call isNumeric() at all? 你已经从std::is_same得到你的答案了,那么为什么要调用std::is_same isNumeric()呢?

There are two ways to solve this problem. 有两种方法可以解决这个问题。

  1. Add addNumeric() to String . addNumeric()添加到String This is the easiest solution if you have permission to modify String . 如果您有权修改String这是最简单的解决方案。
  2. If you don't have permission to modify 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.

相关问题 C++ 编译时检查模板类型中是否存在方法 - C++ compile time check if method exists in template type C ++非类型模板参数编译时间检查 - C++ non-type template parameter compile time check 需要一种检查模板类型的方法,如果不在允许的类型范围内,则在 C++ 中出现编译时错误 - Need a way to check template type and if not in the range of allowed types then have compile time error in C++ C ++模板MetaProgramming:在模板类型上编译时间条件运算符 - C++ Template MetaProgramming: Compile Time Conditional Operator on Template Type C ++如何在编译时检查模板参数类的签名 - C++ how to check the signature of a template parameter class at compile time C ++在编译期间比较模板类型 - C++ Compare template type during compile time C ++如何在编译时检查变量映射的类型 - C++ How to check the type of a variant map at compile time C ++中虚函数的编译时静态类型检查 - Compile-time static type check of virtual functions in C++ C ++ Templatized类型检查编译时线程安全吗? - C++ Templatized type check compile time thread safe? 编译时检查是模板类型还是向量 - Check at compile-time is a template type a vector
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM