Search code examples
c++c++11templatesvariadic-templatessfinae

String class constructor accepting list of const char*


In my String class, I want to make a ctor that accept variable length of arguments (const char*) like parameter pack with variadic template.

Something like following

class String
{
public: 
    
    String(const char*... xList)
    {
         // Internally appending all const char* present in xList and 
         // populating String class char buffer
    } 

};

Any idea how to achieve this? I was under impression that following thing should work... but it is not.

template <const char* ... Args>
String(Args... xList)
{
    
} 

There may be a way by using va_arg but I am not interested in that.


Solution

  • Here is a working example using variadic templates and SFINAE which won't compile if you don't provide const char*s

    #include <type_traits>
    #include <list>
    #include <iostream>
    
    struct String
    {
        std::list<char> ls;
        template<class ... Args, class = std::enable_if_t<std::is_same_v<std::common_type_t<Args...>, const char *>>>
        String(Args...args):ls{*args...}
        {
        }
    
    };
    
    int main(){
        auto c1 = 'a'; const char * pc1 = &c1;
        auto c2 = 'b'; const char * pc2 = &c2;
        auto c3 = 'c'; const char * pc3 = &c3;
        String s{pc1, pc2, pc3};
    
        for(auto it = s.ls.begin();it != s.ls.end(); ++it)std::cout << *it;
    }
    

    Live

    With c++11, the code can be like this

    #include <type_traits>
    #include <list>
    #include <iostream>
    
    struct String
    {
        std::list<char> ls;
    
        template<class ... Args, class = typename std::enable_if<std::is_same<typename std::common_type<Args...>::type, const char *>::value>::type>
        String(Args...args):ls{*args...}
        {
        }
    
    };
    
    int main(){
        auto c1 = 'a'; const char * pc1 = &c1;
        auto c2 = 'b'; const char * pc2 = &c2;
        auto c3 = 'c'; const char * pc3 = &c3;
        String s{pc1, pc2, pc3};
    
        for(auto it = s.ls.begin();it != s.ls.end(); ++it)std::cout << *it;
    }
    

    Live