Compile error with initializer_list when trying to use it to initialize member value of class

Posted by ilektron on Stack Overflow See other posts from Stack Overflow or by ilektron
Published on 2013-11-12T21:50:52Z Indexed on 2013/11/12 21:53 UTC
Read the original article Hit count: 267

Filed under:
|
|

I am trying to make a class initializable from an initialization_list in a class constructor's constructor's initialization list. It works for a std::map, but not for my custom class. I don't see any difference other than templates are used in std::map.

#include <iostream>
#include <initializer_list>

#include <string>
#include <sstream>
#include <map>
using std::string;

class text_thing
{
private:
    string m_text;

public:
    text_thing()
    {

    }

    text_thing(text_thing& other);
    text_thing(std::initializer_list< std::pair<const string, const string> >& il);

    text_thing& operator=(std::initializer_list< std::pair<const string, const string> >& il);

    operator string()
    {
        return m_text;
    }

};


class static_base
{
private:
    std::map<string, string> m_test_map;
    text_thing m_thing;

    static_base();


public:
    static static_base& getInstance()
    {
        static static_base instance;
        return instance;
    }

    string getText()
    {
        return (string)m_thing;
    }

};


typedef std::pair<const string, const string> spair;

text_thing::text_thing(text_thing& other)
{
    m_text = other.m_text;
}

text_thing::text_thing(std::initializer_list< std::pair<const string, const string> >& il)
{
    std::stringstream text_gen;
    for (auto& apair : il)
    {
        text_gen << "{" << apair.first << ", " << apair.second << "}" << std::endl;
    }
}

text_thing& text_thing::operator=(std::initializer_list< std::pair<const string, const string> >& il)
{
    std::stringstream text_gen;
    for (auto& apair : il)
    {
        text_gen << "{" << apair.first << ", " << apair.second << "}" << std::endl;
    }

    return *this;
}

static_base::static_base() :
        m_test_map{{"test", "1"}, {"test2", "2"}},  // Compiler fine with this
        m_thing{{"test", "1"}, {"test2", "2"}}      // Compiler doesn't like this
{

}

int main()
{

    std::cout << "Starting the program" << std::endl;

    std::cout << "The text thing: " << std::endl << static_base::getInstance().getText();

}

I get this compiler output

g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"static_base.d" -MT"static_base.d" -o "static_base.o" "../static_base.cpp"
Finished building: ../static_base.cpp

Building file: ../test.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"test.d" -MT"test.d" -o "test.o" "../test.cpp"
../test.cpp: In constructor ‘static_base::static_base()’:
../test.cpp:94:40: error: no matching function for call to ‘text_thing::text_thing(<brace-enclosed initializer list>)’
   m_thing{{"test", "1"}, {"test2", "2"}}
                                        ^
../test.cpp:94:40: note: candidates are:
../test.cpp:72:1: note: text_thing::text_thing(std::initializer_list<std::pair<const std::basic_string<char>, const std::basic_string<char> > >&)
 text_thing::text_thing(std::initializer_list< std::pair<const string, const string> >& il)
 ^
../test.cpp:72:1: note:   candidate expects 1 argument, 2 provided
../test.cpp:67:1: note: text_thing::text_thing(text_thing&)
 text_thing::text_thing(text_thing& other)
 ^
../test.cpp:67:1: note:   candidate expects 1 argument, 2 provided
../test.cpp:23:2: note: text_thing::text_thing()
  text_thing()
  ^
../test.cpp:23:2: note:   candidate expects 0 arguments, 2 provided
make: *** [test.o] Error 1

Output of gcc -v

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.1-2ubuntu1~13.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu                                                                                                                                                                                                     
Thread model: posix                                                                                                                                                                                                                                                            
gcc version 4.8.1 (Ubuntu 4.8.1-2ubuntu1~13.04) 

It compiles fine with the std::map constructed this way, and if I modify the static_base to return the strings from the maps, all is fine and dandy.

Please help me understand what is going on here.

© Stack Overflow or respective owner

Related posts about c++

Related posts about c++11