模板化使用无法 Select 模板函数用作 Visual Studio 中的参数
Templated usings Can't Select Template Functions to use as Parameters in Visual Studio
这已经是我能做的最简单的玩具示例了,但仍然存在错误:
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
来自 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 版本 15.6.7:
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
如果我不将 using
语句作为模板参数传递,这在 c++14 in g++: https://ideone.com/PU3oBV It'll even work fine on visual-studio-2017 上工作正常:
template <typename T>
typename decltype(make_func(&VectorVolume<double>))::result_type func(const T& dir) {
return VectorVolume(dir.x, dir.y, dir.z);
}
这几乎与我在这里解决的问题相同: 不幸的是,在那种情况下,我只能用 result_of
调用替换我的函数构造。在这种情况下,我只是看不出如何重新设计 make_func
来解决这个错误。有谁知道解决方法? (除了升级到 15.9.5,这确实解决了这个问题。)
作为解决方法,您可以简单地执行以下操作:
template <typename T>
auto func(const T& dir)
-> decltype(VectorVolume(dir.x, dir.y, dir.z))
{
return VectorVolume(dir.x, dir.y, dir.z);
}
您真的只对 function::result_type
感兴趣,所以真的没有必要经历 returning a function
的错误路径。只需 return 结果类型并对其执行 decltype (您甚至不需要定义该函数,因为您实际上并没有调用它。)像这样:
template <typename R, typename... ARGS>
R make_func(R(*)(ARGS...));
然后直接使用return类型:
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 上非常有效,并且作为额外的奖励完全 c++14 compatible: https://ideone.com/gcYo8x
这已经是我能做的最简单的玩具示例了,但仍然存在错误:
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
来自 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 版本 15.6.7:
error C2039:
result_type
: is not a member of 'global namespace' error C2061: syntax error: identifierfunc
error C2143: syntax error: missing;
before{
error C2447:{
: missing function header (old-style formal list?) error C3861:func
: identifier not found
如果我不将 using
语句作为模板参数传递,这在 c++14 in g++: https://ideone.com/PU3oBV It'll even work fine on visual-studio-2017 上工作正常:
template <typename T>
typename decltype(make_func(&VectorVolume<double>))::result_type func(const T& dir) {
return VectorVolume(dir.x, dir.y, dir.z);
}
这几乎与我在这里解决的问题相同:result_of
调用替换我的函数构造。在这种情况下,我只是看不出如何重新设计 make_func
来解决这个错误。有谁知道解决方法? (除了升级到 15.9.5,这确实解决了这个问题。)
作为解决方法,您可以简单地执行以下操作:
template <typename T>
auto func(const T& dir)
-> decltype(VectorVolume(dir.x, dir.y, dir.z))
{
return VectorVolume(dir.x, dir.y, dir.z);
}
您真的只对 function::result_type
感兴趣,所以真的没有必要经历 returning a function
的错误路径。只需 return 结果类型并对其执行 decltype (您甚至不需要定义该函数,因为您实际上并没有调用它。)像这样:
template <typename R, typename... ARGS>
R make_func(R(*)(ARGS...));
然后直接使用return类型:
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 上非常有效,并且作为额外的奖励完全 c++14 compatible: https://ideone.com/gcYo8x