Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在Visual Studio 2017中支持可变模板类型_C++_Visual Studio_Templates_Metaprogramming_C++17_C++14 - Fatal编程技术网

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功能:

  • 使用变量声明(支持包扩展)
  • 具有基类的聚合
  • 类模板参数推断
在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)