c++ - Variadic template argument deduction fails when passing initializer lists -


bar holds std::vector of std::pairs of std::arrays of foovalueadaptors. foovalueadaptor implicitly converts int bool foovalue, makes little sense in contrived example, perfect sense in application. implemented convenience function bar::addentries adding multiple entries @ once, calling more 2 arguments fails compile using gcc 4.8.0. see error messages below.

#include <array> #include <utility> #include <vector>  enum class foovalue {     a,     b,     c };  class foovalueadaptor { public:     foovalueadaptor(bool value)         : m_value(static_cast<foovalue>(value)) {     }      foovalueadaptor(int value)         : m_value(static_cast<foovalue>(static_cast<bool>(value))) {     }      foovalueadaptor(foovalue value)         : m_value(value) {     }      operator foovalue() {         return m_value;     }      operator bool() {         return m_value == foovalue::c;     }  private:     foovalue m_value; };  template<std::size_t nfirst, std::size_t nsecond> class bar { public:     typedef std::array<foovalueadaptor, nfirst> first;     typedef std::array<foovalueadaptor, nsecond> second;     typedef std::pair<first, second> entry;      bar()         : m_table() {     }      void addentry(first first, second second) {         m_table.push_back(std::make_pair(first, second));     }      template <typename... args>     void addentries() {     }      template <typename... args>     void addentries(first first, second second, args... args) {         addentry(first, second);         addentries(args...);     }  private:     std::vector<entry> m_table; };  int main(int argc, char **argv) {     bar<2, 1> b;      b.addentry({ 0, 0 }, { 0 });     b.addentries(         { 0, 1 }, { 0 },         { 1, 0 }, { 0 },         { 1, 1 }, { 1 }     );      return 0; } 

compiler error messages:

test.cpp: in function ‘int main(int, char**)’: test.cpp:74:2: error: no matching function call ‘bar<2ul, 1ul>::addentries(<brace-enclosed initializer list>, <brace-enclosed initializer list>, <brace-enclosed initializer list>, <brace-enclosed initializer list>, <brace-enclosed initializer list>, <brace-enclosed initializer list>)’   );   ^ test.cpp:74:2: note: candidates are: test.cpp:53:7: note: template<class ... args> void bar<nfirst, nsecond>::addentries() [with args = {args ...}; long unsigned int nfirst = 2ul; long unsigned int nsecond = 1ul]   void addentries() {        ^ test.cpp:53:7: note:   template argument deduction/substitution failed: test.cpp:74:2: note:   candidate expects 0 arguments, 6 provided   );   ^ test.cpp:57:7: note: void bar<nfirst, nsecond>::addentries(bar<nfirst, nsecond>::first, bar<nfirst, nsecond>::second, args ...) [with args = {}; long unsigned int nfirst = 2ul; long unsigned int nsecond = 1ul; bar<nfirst, nsecond>::first = std::array<foovalueadaptor, 2ul>; bar<nfirst, nsecond>::second = std::array<foovalueadaptor, 1ul>]   void addentries(first first, second second, args... args) {        ^ test.cpp:57:7: note:   candidate expects 2 arguments, 6 provided 

how can compiler's deduction along?

you need tell compiler explicitly need:

void addentries(std::initializer_list<std::pair<first, second>> il) {    for( const auto& e : il ) {       addentry(e.first,e.second);    } } 

and call this:

b.addentry({{ 0, 0 }}, {{ 0 }}); b.addentries({     {{{ 0, 1 }}, {{ 0 }}},     {{{ 1, 0 }}, {{ 0 }}},     {{{ 1, 1 }}, {{ 1 }}} }); 

notice huge amount of curly brackets, think above correct syntax. fewer brackets accepted both gcc 4.8 , clang 3.2, clang gives lots of warnings, above fixes that. people working on "fix", that'll take time.


Comments

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -