在VS2010-VS2015下进行编译时,如何使用decltype作为较大类型表达式的LHS

时间:2018-11-05 13:01:14

标签: c++ visual-c++ decltype declval

我有两个使用decltypedeclval的代码版本。一种有效,一种无效。它们包括在下面。我已经在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 :(得分:1)

要取悦那些有问题的MSVC,可以部分(https://play.nativescript.org/?template=play-vue&id=5OsNCC&v=3)进行:

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

using Tnew = Told;是更好的语法;)