Decltype comparison

Is there a way to compare the result decltypein C ++ 11?

In other words, why is this code invalid:

template<typename T, typename U>
void func(T& t, U& u) {
    if(decltype(t) == decltype(u)) {
        // Some optimised version for this case
    } else {
        // A more general case for differing types
    }
}

I know that in some cases this particular problem can be solved by partial specialized specialization; my question is about comparing decltypes.

Change: . The question arose when trying to provide default values ​​for free features through SFINAE. Perhaps the best question is why this is not true:

template<bool B>
bool SomeFunction() { ... }

template<typename T, typename U>
bool SomeFunctionWrapper(T& t, U& u) {
    SomeFunction<decltype(t) == decltype(u)>();
}

Since then, I have found another solution (which does not include templates at all), but at one point I tried this:

// If it exists, the free function is defined as
// bool AFreeFunction();
typedef struct { char } undefined;
template<typename T = void>
undefined AFreeFunction();

template<bool B>
bool AFreeFunctionWrapper_() {
    return false;
}

template<>
bool AFreeFunctionWrapper_<false>() {
    return AFreeFunction();
}

bool AFreeFunctionWrapper() {
    return AFreeFunctionWrapper_<decltype(AFreeFunction()) == decltype(undefined)>();
}

, GCC 4.6, , MSVC, 2012 RC. , :

class AFreeFunction {
public:
    operator bool() { return false; }
};

, . , , bool.

+5
3

. , " " t u - T& U&, . , std::is_same. :

template<class T>
void f(T& v1, T& v2){ ... } // #1

template<class T, class U>
void f(T& t, U& u){ ... } // #2

# 1 , # 2, f . - , :

#include <type_traits>

namespace detail{
template<class T, class U>
void f(T& t, U& u, std::true_type){ ... } // #1

template<class T, class U>
void f(T& t, U& u, std::false_type){ ... } // #2
} // detail::

template<class T, class U>
void f(T& t, U& u){
  detail::f(t, u, std::is_same<T,U>()); // tag dispatching
}

std::is_same std::true_type, , std::false_type, .

+8

? decltype , , . -

if (int == int)

, , .

. .

typeid , , , ( ).

+4

You can do this using SFINAE ( std::enable_if):

template<typename T, typename U>
typename std::enable_if<std::is_same<T, U>::value, void>::type func(T& t, U& u) {
    std::cout << "same\n";
}
template<typename T, typename U>
typename std::enable_if<!std::is_same<T, U>::value, void>::type func(T& t, U& u) {
    std::cout << "different\n";
}

As Mehrdad says, decltype(t)they decltype(u)are types ( T &and, U &accordingly), not values, therefore they cannot be compared at the level of expression-value, but they need to be compared in the meta-expression (template) level.

+3
source

All Articles