【问题标题】:How to detect type of expression?如何检测表达式的类型?
【发布时间】:2014-02-05 11:46:09
【问题描述】:

有时,代码中会出现复杂的表达式。例如,大量使用 Boost 库会吸引这些表达式。如果我想typedef这些表达式的类型,我需要写出它的类型。有没有办法在编译时(edit: 或运行时)知道这种类型?也许,Boost 提供了适当的功能。我想用它喜欢

#pragma message (...expression...)

编辑:如果编译时类型检测存在问题,那么运行时类型检测也适用。例如,像下面这样的函数将适合

template <typename T> std::string detectExpressionType(T t);

【问题讨论】:

  • c++11 添加了 decltype 关键字,但是当您标记问题 c++03...
  • 请大家不要再提decltype()了。该问题被标记为 C++03,所以问题实际上是:我没有 C++11 decltype,sp 如何在编译时检测表达式的类型?
  • @Manu343726 decltype 至少是一个有用的搜索词,可用于查找 C++11 之前的非标准关键字和类似的笨拙技术,这些技术促成了 decltype 的标准化。

标签: c++ gcc boost c++03


【解决方案1】:

在 C++03 中你可以使用模板参数推导:

template<typename T>
void foo(T x)
{
    // Now you have the type of the expression.
}

int main()
{
    foo(1.0f * 2.0f);
}

但是,您不能将它用于您的 #pragma message (...expression...) 案例,因为 #pragma 是一个预处理器指令。在预处理阶段你不能真正使用任何类型信息。

【讨论】:

  • 一些库故意创建一个错误,生成一条消息,他们发现恰好记录了他们所针对的编译器上的问题类型 - 例如。通过尝试将值转换为某种类型,从而产生“无法从类型 XYZ 转换为 ”消息。这种方法不允许自定义消息并且可能会造成混淆,但它可能会在前面加上 #pragma message 解释更多关于上下文的信息......
【解决方案2】:

如果您需要它进行调试 - 让它失败。如果运行时信息足够好,您可以对类型进行 demangle(在 demangle 下方用于 gcc)。

#include <iostream>
#include <iostream>
#include <typeinfo>
#include <cxxabi.h>

template <typename T> struct DebugType;
template <typename T>
inline void debug_type() {
    DebugType<T>();
}
template <typename T>
inline void debug_type(const T&) {
    DebugType<T>();
}

std::string demangle(const std::string& source_name)
{
    std::string result;
    size_t size = 4096;
    // __cxa_demangle may realloc()
    char* name = static_cast<char*>(malloc(size));
    try {
        int status;
        char* demangle = abi::__cxa_demangle(source_name.c_str(), name, &size, &status);
        if(demangle) result = demangle;
        else result = source_name;
    }
    catch(...) {}
    free(name);
    return result;
}

template <typename T>
inline void log_type() {
    std::clog << demangle(typeid(T).name()) << '\n';
}

template <typename T>
inline void log_type(const T&) {
    std::clog << demangle(typeid(T).name()) << '\n';
}

int main()  {
    // error: incomplete type ‘DebugType<int>’ used in nested name specifier
    // debug_type<int>();
    log_type<int>();

    // // error: invalid use of incomplete type ‘struct DebugType<std::basic_istream<char> >
    // debug_type(std::cin);
    log_type(std::cin);
    return 0;

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多