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
,这也是非常有用的……但是,
如何在这个上下文中使用
呢?@darkwander
templateusing detaction\u t=typename std::detacy::type;
,现在你可以
detacy\tDE > <代码> >没有代码< >类型名<代码> > @ 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;
}