1

I am trying to create a function that accepts variable number of arguments. But I am getting error in expression decltype(std::initializer_list::size_type) res1=0; as error: expected primary-expression before 'decltype'. The purpose is to declare appropriate variable type that can hold sum of the list (although this declaration will create big enough variable to hold all elements of the list only and not their sum). How can I do this?

Also, how can I make appropriate function return type to return res1 instead of void?

#include <iostream>
#include <initializer_list>

void sum1(std::initializer_list<int> lst1)
{
    decltype(std::initializer_list::size_type) res1=0;
    for(auto v1:lst1)
    {
        res1 += v1;
    }
    std::cout<<" sum = \n"<<res1;
}
int main()
{
    sum1({1,2,3,4,5,6,7,8,9,10});
    //auto b = sum1({1,2,3,4,5,6,7,8,9,10});
    return 0;
}
2
  • You're probably looking for decltype(lst1)::value_type. But if you know your function always accepts initializer_list<int>, then you should declare the result type as long long res1 = 0;, or you could check if your compiler supports a 128 bit integer and use that type instead. Commented Dec 31, 2017 at 2:34
  • 1
    Consider using std::accumulate() instead of for(), then you can use auto to declare res1, eg: auto res1 = std::accumulate(lst1.begin(), lst1.end(), 0); Commented Dec 31, 2017 at 7:21

2 Answers 2

1

size_type is not needed for anything in your function. The initializer_list has type int, therefore res1 should be an int and your return type should be int. If you really want to derive the value type from the initializer_list then do so like this:

#include <iostream>
#include <initializer_list>

auto sum1(std::initializer_list<int> lst1)
{
    typename std::initializer_list<int>::value_type res1 = 0;
    for(auto v1:lst1)
    {
        res1 += v1;
    }

    return res1;
}

int main()
{
    sum1({1,2,3,4,5,6,7,8,9,10});
    auto b = sum1({1,2,3,4,5,6,7,8,9,10});
    std::cout << b << std::endl;
    return 0;
}

If you want the function to be generic, in which case it is necessary to derive the value type, then the template function looks like this.

#include <iostream>
#include <initializer_list>

template<typename T>
auto sum1(std::initializer_list<T> lst1)
{
    typename std::initializer_list<T>::value_type res1 = 0;
    for(auto v1:lst1)
    {
        res1 += v1;
    }

    return res1;
}

int main()
{
    sum1({1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.10});
    auto b = sum1({1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.10});
    std::cout << b << std::endl;
    return 0;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Note that Return Type Deduction requires C++14 or later. For C++11, you have to explicitly specify a trailing return type when using auto, eg: auto sum1(std::initializer_list<int> lst1) -> int or auto sum1(std::initializer_list<T> lst1) -> T
0

Following is corrected code.

#include <iostream>
#include <initializer_list>

int sum1(std::initializer_list<int> lst1)
{
    int res1=0;
    for(auto v1:lst1)
    {
        res1 += v1;
    }
    return res1;
}
int main()
{
    std::cout<<" sum = "<<sum1({1,2,3,4,5,6,7,8,9,10});
    //auto b = sum1({1,2,3,4,5,6,7,8,9,10});
    return 0;
}

You can see working here.

Note: You can change the type of res0 to long or other type if result is not in the limits of int. Also, Change the return type of function sum1 accordingly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.