Templates 基于std::begin()返回类型专门化尾部返回类型
作为练习,我想为容器创建一个通用的模板求和函数。虽然“嵌套模板”重载很好地实现了我的目标,但我想编写一个完全基于Templates 基于std::begin()返回类型专门化尾部返回类型,templates,visual-studio-2012,c++11,sfinae,trailing-return-type,Templates,Visual Studio 2012,C++11,Sfinae,Trailing Return Type,作为练习,我想为容器创建一个通用的模板求和函数。虽然“嵌套模板”重载很好地实现了我的目标,但我想编写一个完全基于std::begin()/std::end()的函数,以允许它处理那些函数重载的所有内容,并充分利用C++11 SFINAE的强大功能 但是,我在返回类型方面遇到了问题。下面是我尝试的,通过数字容器的通用“sum”函数: 首先,使用代码: int arr[] = {1,2,3,4}; vector<int> vec(begin(arr),end(arr)); auto
std::begin()
/std::end()
的函数,以允许它处理那些函数重载的所有内容,并充分利用C++11 SFINAE的强大功能
但是,我在返回类型方面遇到了问题。下面是我尝试的,通过数字容器的通用“sum”函数:
首先,使用代码:
int arr[] = {1,2,3,4};
vector<int> vec(begin(arr),end(arr));
auto sum1 = sum(vec);
auto sum2 = sum(arr);
这会产生一个错误:C2923:'std::remove_const':'std::remove_reference::type'不是参数'\u Ty'
的有效模板类型参数(奇怪,因为这同样适用于val_type
2.使用容器[0]
template<typename T> auto sum(const T& container) -> decltype(container[0])
结果:错误C2061:语法错误:标识符“type”
有什么想法吗?很简单:
decltype(*std::begin(container))
在T常量中解析。
应用与val\u type
相同的操作,添加一些typename
关键字,它就会工作
为什么typename是必需的?请查看错误:
error: expected a type, got ‘std::remove_reference<decltype (* std::begin(container))>::type’
错误:应为类型,但得到“std::remove\u reference::type”
如果您尝试在该表达式之前添加typename,您现在有:
error: need ‘typename’ before
‘std::remove_const<typename std::remove_reference<decltype (* std::begin(container))>::type>::type’
because
‘std::remove_const<typename std::remove_reference<decltype (* std::begin(container))>::type>’
is a dependent scope
错误:之前需要“typename”
'std::remove_const::type'
因为
'std::remove_const'
是一个从属作用域
GCC 4.7.2的工作示例:
#include <iostream>
#include <type_traits>
#include <vector>
using namespace std;
template <class T>
auto sum (T const & container)
-> typename remove_const<typename remove_reference<decltype(*begin(container))>::type>::type
{
typedef typename remove_const<typename remove_reference<decltype(*begin(container))>::type>::type val_type;
val_type sum;
if (is_arithmetic<val_type>::value)
sum = 0;
for (const auto& value: container)
sum = sum + value;
return sum;
}
int main ()
{
vector<int> v { 0, 1, 2, 3 };
cout << sum(v) << endl;
}
#包括
#包括
#包括
使用名称空间std;
模板
自动求和(T常量和容器)
->typename删除_const::type
{
typedef typename remove_const::type val_type;
val_型和;
if(is_算术::值)
总和=0;
用于(常量自动和值:容器)
总和=总和+价值;
回报金额;
}
int main()
{
向量v{0,1,2,3};
我想我可能没有真正理解它。typename
很好地解决了它。谢谢你!@Yakk感谢std::detacy
,这也是非常有用的……但是,如何在这个上下文中使用呢?@darkwandertemplateusing detaction\u t=typename std::detacy::type;
,现在你可以detacy\t
DE > <代码> >没有代码< >类型名<代码> > @ YAKK尽管有4年C++经验-每天都有新的东西:“欢呼!”
error: expected a type, got ‘std::remove_reference<decltype (* std::begin(container))>::type’
error: need ‘typename’ before
‘std::remove_const<typename std::remove_reference<decltype (* std::begin(container))>::type>::type’
because
‘std::remove_const<typename std::remove_reference<decltype (* std::begin(container))>::type>’
is a dependent scope
#include <iostream>
#include <type_traits>
#include <vector>
using namespace std;
template <class T>
auto sum (T const & container)
-> typename remove_const<typename remove_reference<decltype(*begin(container))>::type>::type
{
typedef typename remove_const<typename remove_reference<decltype(*begin(container))>::type>::type val_type;
val_type sum;
if (is_arithmetic<val_type>::value)
sum = 0;
for (const auto& value: container)
sum = sum + value;
return sum;
}
int main ()
{
vector<int> v { 0, 1, 2, 3 };
cout << sum(v) << endl;
}