模板化的用法不能嵌套在Visual Studio中 [英] Templated usings Can't be Nested in Visual Studio

查看:112
本文介绍了模板化的用法不能嵌套在Visual Studio中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这大约简化了,我可以制作一个玩具示例,但仍然会遇到错误:

This is about as simplified as I could make a toy example that still hit the bug:

struct Vector3f64 {
    double x;
    double y;
    double z;
};

struct Vector3f32 {
    float x;
    float y;
    float z;
};

// I use this to select their element type in functions:
template <typename T>
using param_vector = std::conditional_t<std::is_same_v<std::remove_const_t<std::remove_reference_t<T>>, Vector3f64>, double, float>;

// This is the function I want to pull the return type from:
template <typename T>
T VectorVolume(const T x, const T y, const T z) {
    return x * x + y * y + z * z;
}

template<typename F, typename T>
using call_t = decltype(std::declval<F>()(std::declval<T>(), std::declval<T>(), std::declval<T>()));

// This function fails to compile:
template <typename T>
call_t<decltype(&VectorVolume<param_vector<T>>), param_vector<T>> func(const T& param) {
    return VectorVolume(param.x, param.y, param.z);
}

int main() {
    const Vector3f64 foo{ 10.0, 10.0, 10.0 };

    std::cout << func(foo) << std::endl;
}

call_t 是来自 Guillaume Racicot的答案,我想用它来查找返回类型。但是我从visual -studio-2017 版本15.6.7:

The call_t is from Guillaume Racicot's answer which I wanted to use to find a return type. But I get this error from visual-studio-2017 version 15.6.7:

error C2064: term does not evaluate to a function taking 3 arguments<br>
note: see reference to alias template instantiation 'call_t<unknown-type,double>' being compiled
note: see reference to function template instantiation 'unknown-type func(const T &)' being compiled

在g ++上可以正常使用: https://coliru.stacked-crooked.com/a/48b18b66c39486ef 它甚至可以在如果我未通过一个使用语句到另一个:

This works fine on g++: https://coliru.stacked-crooked.com/a/48b18b66c39486ef It'll even work fine on visual-studio-2017 if I don't pass one using statement to another:

template <typename T>
call_t<decltype(&VectorVolume<param_vector<T>>), double> func(const T& param) {
    return VectorVolume(param.x, param.y, param.z);
}

有没有办法解决这个问题?

Is there a way I can work around this?

推荐答案

如@NathanOliver所述,正确的解决方案是将其升级到15.9.5。但是除非您可以使用 result_of invoke_result 通过将 call_t 更改为:

As mentioned by @NathanOliver the right solution is to upgrade to 15.9.5 where this is fixed. But barring that you can use result_of or invoke_result to solve that on 15.6.7 by changing call_t to:

template<typename F, typename T>
using call_t = result_of_t<F&&(T, T, T)>;

请注意,result_of href = / questions / tagged / c%2b%2b17 class = post-tag title =显示标记为'c ++ 17'的问题 rel = tag> c ++ 17 您正在使用 / std:c ++ 17或 / std:c ++ latest运行,这将不起作用,您需要使用更方便的方法:

Note that result_of is deprecated in c++17 so if you are running with "/std:c++17" or "/std:c++latest" this won't work, you'll need to use the more convenient:

template<typename F, typename T>
using call_t = invoke_result_t<F, T, T, T>;

值得注意的是, Guillaume Racicot的答案使用了优美的Veradic模板,该模板也分别用作: template< typename F,typename ... Args>使用call_t = result_of_t< F&&(Args& ...)> template< typename F,typename ... Args>使用call_t = invoke_result_t< F,Args ...> ;; 如果将 func 的定义更改为:

It's worth noting that Guillaume Racicot's answer used an elegant veradic template, which also works respectively as: template <typename F, typename... Args> using call_t = result_of_t<F&&(Args&&...)> or template<typename F, typename... Args> using call_t = invoke_result_t<F, Args...>; if you change your definition of func to:

template <typename T>
call_t<decltype(&VectorVolume<param_vector<T>>), param_vector<T>, param_vector<T>, param_vector<T>> func(const T& param) {
    return VectorVolume(param.x, param.y, param.z);
}

这篇关于模板化的用法不能嵌套在Visual Studio中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆