在编译时打印模板类型名

新手上路,请多包涵

在 C++ 中创建模板函数时,是否有一种简单的方法可以将模板的类型名表示为字符串?我有一个简单的测试用例来显示我正在尝试做的事情(注意显示的代码无法编译):

 #include <stdio.h>
template <typename type>
type print(type *addr)
{
  printf("type is: %s",type);
}

int main()
{
  int a;
  print(&a);
}

// Would like to print something like:
// type is: int

我认为当函数被实例化时,类型名应该在编译时可用,但我对模板不太熟悉,我还没有看到将类型名作为字符串获取的方法。

我想这样做的原因是为了进行一些 printf 类型的调试。我有多个线程正在运行,并且使用 gdb 单步执行会更改程序行为。因此,对于某些事情,我想转储有关正在执行哪些功能的信息。这不是太重要,所以如果解决方案过于复杂,我会跳过将此信息添加到我的日志记录功能。但是,如果有一种简单的方法可以做到这一点,那将是有用的信息。

原文由 Gabriel Southern 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

__PRETTY_FUNCTION__ 应该可以解决您的问题(至少在运行时)

下面程序的输出是:

 asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf void tempFunction() [with type = bool]
asfdasdfasdf void tempFunction() [with type = bool]
asfdasdfasdf void tempFunction() [with type = bool]
asfdasdfasdf void tempFunction() [with type = bool]
asfdasdfasdf void tempFunction() [with type = bool]
asfdasdfasdf void tempFunction() [with type = bool]
!!!Hello World!!!

如果你真的真的需要类型名作为字符串,你可以破解它(使用 snprintf 而不是 printf )并在’=‘之后和’]‘之前拉取子字符串。

 #include <iostream>
using namespace std;

template<typename type>
class test
{
public:
test()
{
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
}
};

template<typename type>
void tempFunction()
{
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
    printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
}

int main() {
    test<int> test;

    tempFunction<bool>();
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    return 0;
}

原文由 David D 发布,翻译遵循 CC BY-SA 3.0 许可协议

另一种编译时解决方案,类似于 matiu 提供的解决方案,但可能更具描述性的是使用 static_assert 包装在一个小辅助函数中:

 #include <utility>

template <typename T>
struct always_false : std::false_type { };

template <typename T>
constexpr bool always_false_v = always_false<T>::value;

template <typename T>
void print_type_in_compilation_error(T&&)
{
    static_assert(always_false_v<T>,
                  "Compilation failed because you wanted to know the type; see below:");
}

 // usage:
int I;
print_type_in_compilation_error(I);

上面会给你一个很好的错误消息(在 MSVC 和 Clang 中测试),就像在另一个答案中一样,但我认为代码更容易理解。

注意原始答案中的代码格式不正确,所以我稍微更改了代码。 always_false 这个 答案。

原文由 florestan 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题