Visual Studio中的Decltype强制转换运算符

时间:2017-12-02 14:40:00

标签: c++ c++11 templates visual-c++ decltype

请考虑以下代码示例:

#include <algorithm>

template<class T, class U>
struct lazy_caller{
    lazy_caller(T &&one, U &&two) : m_one(one), m_two(two){} 

    operator decltype(std::max(T(), U()))() const {
        return std::max(m_one, m_two);
    }

    T m_one;
    U m_two;
};

int main()
{
    lazy_caller<int, int> caller(1, 2);
    int i = caller;
    return 0;
}

正如您可能想象的那样,在实际代码中,我希望进行更复杂的类型推导以创建适当的转换运算符。无论如何 - 这段代码不能在VS2017中编译(我猜这与早期版本相同) - 所以我想问一下这个问题是否有解决办法?我已经尝试过了:

operator auto () const

它还会生成编译器错误,如:

source_file.cpp(8): error C2833: 'operator function-style cast' is not a recognized operator or type

msvc是否有解决此问题的方法? 因为gcc对operator autooperator decltype(..)都没有问题。

2 个答案:

答案 0 :(得分:2)

您与operator auto () const关系非常密切。建议的workaround涉及使用C ++ 11函数语法:

operator auto() const -> decltype(std::max(T(), U())) {
    return std::max(m_one, m_two);
}

答案 1 :(得分:1)

  

msvc是否有解决此问题的方法?

通过using别名怎么样?

using maxType = decltype(std::max(T(), U()));

operator maxType () const {
    return std::max(m_one, m_two);
}

或者,更好的是,使用std::declval()

using maxType = decltype(std::max(std::declval<T>(), std::declval<U>()));

如果这不起作用,您可以尝试使用lazy_caller类的第三个默认模板类型;

之类的东西
template <typename T, typename U,
   typename R = decltype(std::max(std::declval<T>(), std::declval<U>()))>
struct lazy_caller
 {
   lazy_caller(T && one, U && two) : m_one(one), m_two(two)
    { } 

   operator R () const
    { return std::max(m_one, m_two); }

   T m_one;
   U m_two;
 };