简体   繁体   English

打印出未知类型变量的值?

[英]Printing out value of variable of unknown type?

I'm trying to write a simple function template in C++ in which I am printing out the value of a variable of unknown type. 我试图用C ++写一个简单的函数模板,在其中打印出未知类型变量的值。 The problem is I can't figure out how to do this since the variable could either be a pointer or a primitive type. 问题是我不知道如何执行此操作,因为变量可以是指针或原始类型。 With the primitive type, I can simply print the value out; 使用基本类型,我可以简单地将值打印出来; but pointers require de-referencing. 但是指针需要取消引用。

The following code gives me an error: 以下代码给我一个错误:

#include <iostream>
#include <type_traits>

using namespace std;

template<typename T>
void foo(T someVar) {
  if(std::is_fundamental<T>::value) {
    cout << "It's primitive! \n" << someVar << endl;
  } else {
    cout << "It's a pointer! \n" << *someVar << endl;
  }
}

int main(int argc, char **argv) {
  int x = 5;
  foo(x);

  int *y = new int();
  *y = 5;

  foo(y);
  delete y;

  return 0;
}

The error I get when I compile is: 编译时出现的错误是:

test.cc: In function 'void foo(T) [with T = int]':
test.cc:19:8:   instantiated from here
test.cc:13:5: error: invalid type argument of unary '*' (have 'int')

It's complaining that I'm trying to de-reference a primitive type from my first call to foo(), but that's exactly why I'm using the if-statement: to check if it's primitive or not. 它抱怨我试图在第一次调用foo()时取消引用原始类型,但这正是为什么我使用if-statement来检查它是否为原始类型的原因。 How would I go about implementing what I'm trying to do? 我将如何实施我想做的事情?

What you need to do, is write 2 versions of your templated function. 您需要做的是编写2个版本的模板化函数。

template<typename T>
void foo(T someVar) {
    cout << "Assume it's primitive! \n" << someVar << endl;
}

template<typename T>
void foo(T* pVar) {
    cout << "This is a pointer! \n" << *pVar << endl;
}

The compiler will choose the pointer version if it works, because it's more specific. 如果可行,编译器将选择指针版本,因为它更具体。 If the type is not a (raw) pointer, it will default to the first version. 如果类型不是(原始)指针,则默认为第一个版本。

If you need smart pointers to be dereferenced, you can further overload your function definition. 如果需要取消智能指针的引用,则可以进一步重载函数定义。

Eg. 例如。

template<typename T>
void foo(std::shared_ptr<T> pVar) {
    cout << "This is a shared pointer! \n" << *pVar << endl;
}

You need an additional layer of indirection. 你需要额外的间接层。

#include <iostream>

template < typename T >
struct print_helper
{
  static void
  print(std::ostream& os, const T& value)
  {
    os << "The value is " << value << "\n";
  }
};

template < typename T >
struct print_helper< T * >
{
  static void
  print(std::ostream& os, const T *const pointer)
  {
    os << "The pointer points to " << *pointer << "\n";
  }
};

template < typename T >
void
foo(T whatever)
{
  print_helper<T>::print(std::cout, whatever);
}


int
main()
{
  const auto a = 42;
  foo(a);
  foo(&a);
}

Output: 输出:

The value is 42
The pointer points to 42

A solution I'm partial to for just printing nicely is to write a function to do the dereferencing. 我只喜欢打印的一种解决方案是编写一个函数进行解引用。

template<typename T> T &deref(T &elem) { return elem; }
template<typename T> T &deref(T *elem) { return *elem; }

Then you can simply use deref(value) anywhere you don't know whether or not value will be a pointer, as long as you don't care which it is. 然后,只要您不关心value是什么,就可以在不知道value是否为指针的任何地方简单地使用deref(value)

template<typename T>
void print(T t) {
    std::cout << deref(t) << '\n';
}

Write the function twice: 编写函数两次:

struct Foo
{
    template<typename T>
    static void foo(T val) {
        cout << "var: " << val << endl;
    }

    template<typename T>
    static void foo(T* val) {
        cout << "ptr: " << *val << endl;
    }
};

To call: 致电:

int x;
int *y;
Foo::foo(x);
Foo::foo(y);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM