C++ 如何检测表达式的类型?

C++ 如何检测表达式的类型?,c++,gcc,boost,c++03,C++,Gcc,Boost,C++03,有时,代码中会出现复杂的表达式。例如,大量使用Boost库吸引了这些表达式。如果我想typedeftype这些表达式,我需要写出它的类型。在编译时(编辑:或运行时),是否有办法知道这种类型?也许Boost提供了适当的功能。我喜欢用它 #pragma message (...expression...) 编辑:如果编译时类型检测有问题,那么运行时类型检测也适用。例如,下面这样的函数将适合 template <typename T> std::string detectExpressi

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

#pragma message (...expression...)
编辑:如果编译时类型检测有问题,那么运行时类型检测也适用。例如,下面这样的函数将适合

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

在C++03中,您可以使用模板参数推断:

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

int main()
{
    foo(1.0f * 2.0f);
}
模板
void foo(T x)
{
//现在您有了表达式的类型。
}
int main()
{
foo(1.0f*2.0f);
}

但是,您不能将其用于
#pragma消息(…表达式…
案例,因为
#pragma
是预处理器指令。您不能在预处理器阶段真正使用任何类型信息。

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

#包括
#包括
#包括
#包括
模板结构调试类型;
模板
内联无效调试类型(){
DebugType();
}
模板
内联无效调试类型(常量T&){
DebugType();
}
std::string demangle(const std::string和源名称)
{
std::字符串结果;
尺寸=4096;
//_uuucxa_udemangle可能会realloc()
char*name=static_cast(malloc(size));
试一试{
智力状态;
char*demangle=abi::uucxa_demangle(source_name.c_str()、name、size和status);
如果(demangle)结果=demangle;
else result=源名称;
}
捕获(…){}
免费(姓名);
返回结果;
}
模板
内联无效日志类型(){

std::clog c++11添加了decltype关键字,但当您标记问题c++03时……请大家停止使用
decltype()
。这个问题被标记为C++03,所以真正的问题是:我没有C++11 decltype,sp如何在编译时检测表达式的类型?@Manu343726
decltype
至少是一个有用的搜索词,可以查找C++11之前的非标准关键字和类似的笨拙技术,这些技术促成了
declty的标准化pe
。一些库故意创建一个错误,生成一条消息,它们发现该消息恰好记录了它们所针对的编译器上的问题类型-例如,尝试将值强制转换为某个类型,从而生成“无法从XYZ类型强制转换为”的消息消息。这种方法不允许自定义消息,可能会造成混乱,但它可能前面会有一条
#pragma消息
解释有关上下文的更多信息。。。。
#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;

}