#include <iostream>
#include <string>
#include <vector>
#include <cstring>

template <typename Container>
Container& do_safe_emplace(Container &c, const char *value)
{
    std::cout << "do_safe_emplace(const char *)\n";
    if (value) c.emplace_back(value);
    return c;
}

template <typename Container>
Container& do_safe_emplace(Container &c, const typename Container::value_type &value)
{
    std::cout << "do_safe_emplace(const value_type &)\n";
    c.emplace_back(value);
    return c;
}

template <typename Container>
Container& safe_emplace(Container &c)
{
    return c;
}

template <typename Container, typename T, typename... Args>
Container& safe_emplace(Container &c, const T &value, Args... args)
{
    do_safe_emplace(c, value); 
    return safe_emplace(c, args...);
}

template <typename Container, typename T>
Container& safe_emplace(Container &c, const std::initializer_list<T> il)
{
    std::cout << "safe_emplace(initializer_list)\n";
    for (auto& value: il)
        do_safe_emplace(c, value);
    return c;
}

int main()
{
    std::vector<std::string> svec;

    char one[] = "string one";
    char two[] = "string two";
    char three[] = "string three";
    std::string four = "string four";
    char* d = new char[11];
    char* n = NULL;

    std::strncpy(d, "0123456789", 11);

    safe_emplace(svec, one);   // char[]
    safe_emplace(svec, two, three, four); // variadic
    safe_emplace(svec, d);  // char* 
    safe_emplace(svec, n); // char* NULL
    safe_emplace(svec, "five", "four", std::string("three"), "two", "one", nullptr);
    safe_emplace(svec, {"A", "B", "C", "D", "E"} );

    for (auto &s : svec)
      std::cout << s << "\n";

    delete[] d; // clean up d (new)

    return 0;
}