模板化的用法不能嵌套在Visual Studio中

时间:2019-03-01 16:55:57

标签: c++ templates visual-studio-2017 using return-type

这与我制作一个仍然能解决问题的玩具示例一样简单:

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's answer,我想用它来查找返回类型。但是我从版本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如果我不将一个using语句传递给另一个语句,它甚至可以在上正常工作。

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

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

1 个答案:

答案 0 :(得分:1)

As mentioned by @NathanOliver正确的解决方案是将其升级到15.9.5。但是除非您可以使用result_of or invoke_result通过将template<typename F, typename T> using call_t = result_of_t<F&&(T, T, T)>; 更改为以下内容才能在15.6.7上解决该问题:

result_of

请注意,中不推荐使用template<typename F, typename T> using call_t = invoke_result_t<F, T, T, T>; ,因此,如果您使用“ / std:c ++ 17”或“ / std:c ++ latest”运行,则无法使用需要使用更方便的方法:

template <typename F, typename... Args> using call_t = result_of_t<F&&(Args&&...)>

值得注意的是,Guillaume Racicot's answer使用了优雅的Veradic模板,如果您将template<typename F, typename... Args> using call_t = invoke_result_t<F, Args...>;的定义更改为:,它也分别用作:functemplate <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); }

{{1}}