Как использовать decltype в качестве LHS выражения большего типа при компиляции в VS2010-VS2015 - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть две версии кода, использующие decltype и declval. Один работает, а другой нет. Они включены ниже. Я проверил это на VS2017 и ниже, и я получаю те же результаты. VS2018 скомпилирует его. GCC и Clang компилируют все это.

Ошибка, которая генерируется для случая сбоя в MSVC:

[x86-64 MSVC 19 2017 RTW # 1] ошибка C3646: «тип»: неизвестное переопределение Спецификатор

для строки

typedef typename decltype(boost::declval<Func>()(SegmentVec()))::value_type type;

См. God Bolt для живой версии приведенного ниже кода.

#include <vector>
#include "boost/type_traits/declval.hpp"

typedef std::vector<int> SegmentVec;

/////////////////////////////////
// The below fails
template <typename Func> struct Traits {
    typedef typename decltype(boost::declval<Func>()(SegmentVec()))::value_type type;
};
template <typename F> auto Hof(F f) -> typename Traits<F>::type {
    return f(std::vector<int>{2})[0];
}
/////////////////////////////////


/////////////////////////////////
// The below works
template <typename Func> struct Traits2 {
    typedef typename decltype(boost::declval<Func>()(SegmentVec())) type;
};
template <typename F> auto Hof2(F f) -> typename Traits2<F>::type {
    return f(std::vector<int>{2});
}
/////////////////////////////////


int main(){
    auto lmd = [](std::vector<int> const & a){return a;}; 

    Hof(lmd);
    Hof2(lmd);
}

Возможно ли получить код для компиляции под MSVC 2010 и более поздних версий без существенного изменения кода. Приведенный выше код сам по себе является извлечением из большей части кода и не обязательно имеет какое-либо значение, кроме демонстрации ошибки компилятора.

1 Ответ

0 голосов
/ 05 ноября 2018

Чтобы угодить этому глючному MSVC, вы можете сделать это частично ( demo ):

template <typename Func> struct Traits {
    typedef decltype(boost::declval<Func>()(SegmentVec())) suptype;
    typedef typename suptype::value_type type;
};

using Tnew = Told; - лучший синтаксис;)

...