C++ 如何在Visual Studio 2017中支持可变模板类型
使用此对象的用户:C++ 如何在Visual Studio 2017中支持可变模板类型,c++,visual-studio,templates,metaprogramming,c++17,c++14,C++,Visual Studio,Templates,Metaprogramming,C++17,C++14,使用此对象的用户: template<class... Ts> struct overload : Ts... { using Ts::operator()...; }; template<class... Ts> overload(Ts...) -> overload<Ts...>; struct fallback_t { template<class T> fallback_t(T&&) {} }; 模板结构重载:Ts。
template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
template<class... Ts> overload(Ts...) -> overload<Ts...>;
struct fallback_t { template<class T> fallback_t(T&&) {} };
模板结构重载:Ts。。。{使用Ts::运算符()…;};
模板重载(Ts…)->重载;
结构回退{模板回退{(t&&){};
不幸的是,我无法在Visual Studio 2017中编译它。我得到了错误:
1> 警告C4346:'Ts::()':依赖名称不是类型1> 注:前缀为“typename”表示类型
1> 注意:请参阅正在编译的类模板实例化“owner::重载”
1> 错误C2143:语法错误:缺少“;”在“…”之前
1> 错误C2059:语法错误:“…”
1> 错误C2238:在“;”之前出现意外标记
1> 错误C2988:无法识别的模板声明/定义
1> 错误C2143:语法错误:在“…”之前缺少“)”
1> 错误C2143:语法错误:缺少“;”在“…”之前
1> 错误C2365:“Ts”:重新定义;以前的定义是“模板参数”
1> 注:参见“Ts”的声明
1> 错误C2238:在“;”之前出现意外标记
1> 错误C2059:语法错误:“…”
1> 错误C2059:语法错误:')'
1> 错误C2955:“所有者::重载”:使用类模板需要模板参数列表
1> 注意:请参见“所有者::重载”的声明
1> 错误C2664:“void owner::bar::
::operator()(owner::fallback\u t)const”:无法将参数1从“owner::fallback\u t”转换为“owner::fallback\u t”
1> 注意:使用未定义的类型“owner::fallback\t”
1> 注意:请参见“所有者::回退”的声明
1> 错误C2672:“所有者::findObject”:未找到匹配的重载函数
1> 错误C2780:“void owner::findObject(int,const T&)”:需要2个参数-1个参数
1> 注:参见“所有者::findObject”的声明
我能做些什么使Visual Studio尊重中的可变模板吗?它仅在C++17中有效。尝试在VisualStudio 2017中用标志>代码> /STD:C++ 17代码>在项目-> Projt>属性> C++ +>语言中编译它。请注意,C++17从Visual Studio 2017.3开始提供。它仅在C++17中有效。尝试在VisualStudio 2017中用标志>代码> /STD:C++ 17代码>在项目-> Projt>属性> C++ +>语言中编译它。请注意,C++17从Visual Studio 2017.3开始提供。这取决于三个单独的C++17功能:
- 使用变量声明(支持包扩展)
- 具有基类的聚合
- 类模板参数推断
模板
结构重载:T,重载{
使用T::operator();
使用重载::运算符();
过载(T,Ts…Ts):T(T),过载(Ts…){
};
模板
结构重载:T{
使用T::operator();
重载(T):T(T){
};
模板
过载使_过载(Ts…Ts){
返回过载(ts…);
}
如果编译器不支持基类的聚合,则需要构造函数;如果编译器不支持类模板的模板参数推断,则需要使用
make_重载。这取决于三个单独的C++17功能:
- 使用变量声明(支持包扩展)
- 具有基类的聚合
- 类模板参数推断
在C++17之前,第一种常见的解决方法是递归继承(为了简单起见,省略了转发):
模板
结构重载:T,重载{
使用T::operator();
使用重载::运算符();
过载(T,Ts…Ts):T(T),过载(Ts…){
};
模板
结构重载:T{
使用T::operator();
重载(T):T(T){
};
模板
过载使_过载(Ts…Ts){
返回过载(ts…);
}
如果编译器不支持基类的聚合,则需要构造函数;如果编译器不支持类模板的模板参数推断,则需要使用make_重载。您可以尝试使用@S.M.指出的/std::c++17
模式进行编译;请注意,一些C++17特性可能会破坏现有代码。此外,正如@milesbudnek所指出的,截至今天,MSVC不支持所需的功能
如果不能使用C++17模式,可以在中实现
我要做一些改变:
template <class... Fs>
struct overload_t;
// zero
template<>
struct overload_t<> {};
// >1
template <class F0, class... Frest>
struct overload_t<F0, Frest...> :
F0,
overload_t<Frest...>
{
overload_t(F0 f0, Frest... rest) :
F0(std::move(f0)), overload_t<Frest...>(std::move(rest)...)
{}
using F0::operator();
using overload_t<Frest...>::operator();
};
// 1
template <class F0>
struct overload_t<F0> : F0
{
overload_t(F0 f0) : F0(std::move(f0)) {}
using F0::operator();
};
template <class... Fs>
auto overload(Fs... fs)
{
return overload_t<Fs...>(std::move(fs)...);
}
模板
结构过载;
//零
模板
结构重载{};
// >1
模板
结构重载\u t:
F0,
超载
{
过载(F0 F0,Frest…静止):
F0(标准::移动(F0)),过载(标准::移动(休息)…)
{}
使用F0::operator();
使用重载_t::运算符();
};
// 1
模板
结构重载\u t:F0
{
重载_t(F0-F0):F0(std::move(F0)){
使用F0::operator();
};
模板
自动过载(Fs…Fs)
{
返回过载(标准::移动(fs)…);
}
正如@S.M.所指出的,您可以尝试使用/std::c++17
模式进行编译;请注意,一些C++17特性可能会破坏现有代码。此外,正如@milesbudnek所指出的,截至今天,MSVC不支持所需的功能
如果不能使用C++17模式,可以在中实现
我要做一些改变:
template <class... Fs>
struct overload_t;
// zero
template<>
struct overload_t<> {};
// >1
template <class F0, class... Frest>
struct overload_t<F0, Frest...> :
F0,
overload_t<Frest...>
{
overload_t(F0 f0, Frest... rest) :
F0(std::move(f0)), overload_t<Frest...>(std::move(rest)...)
{}
using F0::operator();
using overload_t<Frest...>::operator();
};
// 1
template <class F0>
struct overload_t<F0> : F0
{
overload_t(F0 f0) : F0(std::move(f0)) {}
using F0::operator();
};
template <class... Fs>
auto overload(Fs... fs)
{
return overload_t<Fs...>(std::move(fs)...);
}
模板
结构过载;
//零
模板
结构重载{};
// >1
模板
结构重载\u t:
F0,
超载
{
过载(F0 F0,Frest…静止):
F0(标准::移动(F0)),过载(标准::移动(休息)…)
{}
使用F0::operator();
使用重载_t::运算符();
};
// 1
模板
结构重载\u t:F0
{
重载_t(F0-F0):F0(std::move(F0)){
使用F0::operator();
};
模板
自动过载(Fs…Fs)
{
返回过载(标准::移动(fs)…);
}
在C++14中,它类似于:
template <typename ... Ts> struct overload;
template <typename T>
struct overload<T> : T
{
template <typename U>
overload(U&& u) : T(std::forward<U>(u)) {}
using T::operator();
};
template <typename T, typename ... Ts>
struct overload<T, Ts...> : overload<T>, overload<Ts...>
{
template <typename U, typename ... Us>
overload(U&& arg, Us&&... args) : overload<T>(std::forward<U>(arg)),
overload<Ts...>(std::forward<Us>(args)...) {}
using overload<T>::operator();
using overload<Ts...>::operator();
};
template<class... Ts>
overload<std::decay_t<Ts>...> make_overload(Ts&&... args)
{
return {std::forward<Ts>(args)...};
}
模板结构重载;
模板
结构重载:T
{
模板
重载(U&&U):T(标准::向前(U)