模板化的用法无法选择模板函数用作Visual Studio中的参数 [英] Templated usings Can't Select Template Functions to use as Parameters in Visual Studio

查看:68
本文介绍了模板化的用法无法选择模板函数用作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<class R, class... ARGS>
std::function<R(ARGS...)> make_func(R(*ptr)(ARGS...)) {
  return std::function<R(ARGS...)>(ptr);
}

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

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

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

make_func 来自 SergyA的答案,我想创建一个 std:: function ,所以我可以找到一个返回类型,而无需显式声明 VectorVolume 接受的参数.但是我从版本15.6.7:

The make_func is from SergyA's answer which I wanted to create a std::function so I could find a return type without explicitly declaring the parameters VectorVolume took. But I get this error from visual-studio-2017 version 15.6.7:

错误C2039: result_type :不是全局名称空间"的成员错误C2061:语法错误:标识符 func 错误C2143:语法错误:在 {之前缺少; 错误C2447: {:缺少函数标头(旧式的正式列表?)错误C3861: func :找不到标识符

error C2039: result_type: is not a member of 'global namespace' error C2061: syntax error: identifier func error C2143: syntax error: missing ; before { error C2447: {: missing function header (old-style formal list?) error C3861: func: identifier not found

这在 https://ideone.com/PU3oBV 它甚至可以工作在如果我没有通过 using 语句作为模板参数:

This works fine on c++14 in g++: https://ideone.com/PU3oBV It'll even work fine on visual-studio-2017 if I don't pass the using statement as a template parameter:

template <typename T>
typename decltype(make_func(&VectorVolume<double>))::result_type func(const T& dir) {
    return VectorVolume(dir.x, dir.y, dir.z);
}

这几乎与我在这里解决的问题相同:无法在Visual Studio中嵌套使用模板的用法不幸的是,在这种情况下,我可以用 result_of 调用替换函数构造.在这种情况下,我只是看不到如何重新设计 make_func 来解决此错误.有人知道解决方法吗?(除了升级到15.9.5确实可以解决此问题.)

This is almost identical to the problem I worked around here: Templated usings Can't be Nested in Visual Studio Unfortunately, in that case I could just replace my function construction with a result_of call. In this case I just don't see how I can redesign make_func to work around this bug. Does anyone know of a workaround? (Other than upgrading to 15.9.5, which does solve this.)

推荐答案

您真的只对 function :: result_type 感兴趣,因此实际上不需要遍历返回代码的错误路径.功能.只需返回结果类型并在其上执行decltype(您甚至不需要定义该函数,因为您实际上并未对其进行调用.)类似这样的东西:

You're really only interested in the function::result_type so there's really no need to go through the bugged path of returning a function. Just return the result type and do a decltype on that (you don't even need to define the function since you're not actually calling it.) Something like this:

template <typename R, typename... ARGS>
R make_func(R(*)(ARGS...));

然后直接使用返回类型:

Then just directly use the return type:

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

这在Visual Studio 15.6.7上非常有用,并且额外的好处是完全

This is works great on Visual Studio 15.6.7 and as an added bonus is fully c++14 compatible: https://ideone.com/gcYo8x

这篇关于模板化的用法无法选择模板函数用作Visual Studio中的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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