The following code doesn't compile because the instance parameters don't match the constructor parameters. If I remove the constructor it compiles and runs. I would like to be able to use it in either way - constructing with string or direct member variable initialisation. (This is a minimal version of what I'm really trying to do.) Do I need another constructor with an initialiser list or similar?
Specifically, I don't want to add another constructor with two ints, I want to use the mechanism that is used if I delete the string constructor.
#include <iostream>
#include <string>
struct S
{
int m_a;
int m_b;
S(const std::string s):
m_a(99),
m_b(99)
{std::cout << "ctor runs" << std::endl;}
friend std::ostream& operator<<(std::ostream& os, const S& s)
{ os << "S: " << s.m_a << ", " << s.m_b; }
};
int main()
{
S s{1,2};
std::cout << s << std::endl;
}
S(const std::string s)constructor, and instead do astatic S make(const std::string s) { return S{99, 99}; }class factory function, you can have the aggregate construction behavior you want, without writing a constructor with two ints.template <typename ... Ts> S(Ts&&... args) : m_a(sizeof...(Ts) == 2 ? std::get<0>(std::tie(args...)) : 99), m_a(sizeof...(Ts) == 2 ? std::get<1>(std::tie(args...)) : 99) { if (sizeof...(Ts) == 1) { std::cout << "ctor runs\n"; } }:) (need also to protect against copy/move constructor, or check types). (Don't do that).