Below is a example (not the entire class, just relevant parts)
class Container {
private:
size_t m_next_id;
std::unordered_map m_objects;
public:
template<typename Type, typename... Args> size_t create(Args... args) { return this->add(new Type (args...)); }
size_t add(Base * obj) { m_objects.emplace(m_next_id, obj); return m_next_id++; }
}
Say I have the following
class Base;
class A : Base;
class B : Base;
// etc.
Then the following calls work with out error
container.create<B, Vector2f, float>({1, 0}, 0);
container.add(new B({0, 1}, 0));
container.create<B>(Vector2f{0, 1}, 1); // EDIT no initializer list
However the following produce a compile time error
container.create<B>({1, 0}, 1);
Error:
error: no matching function for call to 'Container::create(<brace-enclosed initializer list>, const int&)'
container.create<B>({1, 0}, 1);
^
note: candidate: size_t Container::create(Args ...) [with Type = B; Args = {}; size_t = long long unsigned int]
template<typename Type, typename... Args> size_t create(Args... args) { return this->add(new Type (args...)); }
^~~~~~
note: candidate expects 0 arguments, 2 provided
I'm unsure why the template isn't able to work with this pattern, nor how to fix it so it would work how I want, based on examples I've seen using std emplace functions this should be able to work.
EDIT: Base on the fact that the version with out an initializer list, works fine, I can conclude the problem is because of the initializer list. However I don't see why this would be a problem, shouldn't this be able to construct the appropriate type based on B's constructor where B is invoked?