简体   繁体   中英

std::initializer_list as constructor argument in template class

I'm trying to use std::initializer_list in a constructor to accept variable number of arguments. With non-template class it works fine, but with template class it gives compiling errors. Could anyone possiblly point me to the right direction? My g++ is capable of C++17.

#include <iostream>
#include <vector>
#include <type_traits>
#include <initializer_list>

struct Nontemplate
{
    // std::initializer_list for a function taking variable number of arguments
    template <class Iterator>
    Nontemplate(std::initializer_list<Iterator> list) {
        std::cout << "size: " << list.size() << std::endl;
        for(auto it : list) {
            std::cout << *it << std::endl;
        }
    }
};

template <class T, class TIterator>
struct Template
{
    std::vector<T> vec;

    Template(std::initializer_list<TIterator> list)
    {
        if(!std::is_same<typename std::iterator_traits<TIterator>::value_type, T>::value)
            throw std::runtime_error("Iterator value type is not the expected.");

        std::cout << "size: " << list.size() << std::endl;

        vec.clear();
        vec.reserve(list.size());
        for(T val : list)
            vec.push_back(val);
    }
};

int main()
{
    double vec[] = {0,1,2,3,4,5};

    Nontemplate cls0({vec, vec+2, vec+3, vec+4}); // no problem
    //Template cls1({vec, vec+2, vec+3, vec+4});  // compiling error
    return 0;
}

Thanks in advance.

Template cls1({vec, vec+2, vec+3, vec+4}) has no ways to deduce T.

You might use

Template<double, double*> cls1({vec, vec+2, vec+3, vec+4});

or provide custom deduction guide:

template <typename It>
Template(std::initializer_list<It>)
-> Template<typename std::iterator_traits<It>::value_type, It>;

Or simplify your class to remove that T

template <class TIterator>
struct Template
{
    using T = typename std::iterator_traits<TIterator>::value_type;
    std::vector<T> vec;

    Template(std::initializer_list<TIterator> list)
    {
        std::cout << "size: " << list.size() << std::endl;

        vec.clear();
        vec.reserve(list.size());
        for(T val : list)
            vec.push_back(val);
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM