Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect type of expression?

Tags:

c++

gcc

boost

c++03

Sometimes, there are complicate expressions appear in the code. For example, intensive use of Boost library appeals these expressions. If I want to typedef type of these expression, I need to write out its type. Is there some way to know this type at compile time (edit: or run-time)? Maybe, Boost offers appropriate functionality. I'd like to use it like to

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

EDIT: If there is a problem with compile-time type detection, then run-time type detection fits too. For example, function like the following will suit

template <typename T> std::string detectExpressionType(T t);
like image 219
Oleg Svechkarenko Avatar asked Jan 01 '26 20:01

Oleg Svechkarenko


2 Answers

Well in C++03 you can use template argument deduction:

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

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

You can't use this for your #pragma message (...expression...) case however because #pragma is a preprocessor directive. You can't really use any type information in the preprocessor stage.

like image 51
Simple Avatar answered Jan 03 '26 10:01

Simple


If you need it for debugging - let it fail. If runtime information is good enough you can demangle the type (below the demangle is for 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;

}

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!