Parametry nazwane w C++

0

Taka szarada - może ktoś to już ładniej rozwiązał.
Chciałbym zrobić coś jak "parametry nazwane" w C++, gdzie podaję tylko niektóre parametry do funkcji, niekoniecznie te z początku listy parametrów.
Poniższe rozwiązanie prawie działa (GCC 8). Pytanie brzmi: dlaczego wywołanie nr 3 (zakomentowane) nie działa?

#include <iostream>
using namespace std;

struct Params {
	int p1;
	string p2;
    double p3;
};

string foo(const Params p) {
  string result = "{";
  if (p.p1 != 0) {
  	result += to_string(p.p1);
  }
  
  if (p.p2.length() > 0) {
    if (result.length() > 0) {
    	result += ", ";
    }
    result += p.p2;
  }
  
  if (p.p3 != 0) {
    if (result.length() > 0) {
    	result += ", ";
    }
  	result += to_string(p.p3);
  }
  
  result += "}";
  return result;
}

int main() {
	cout << foo({2}) << endl;
	cout << foo({.p1 = 3, .p2 = "aa"}) << endl;
	cout << foo({.p1 = 3, .p2 = "aa", .p3 = 3.1}) << endl;
	//cout << foo({.p2 = "aa"}) << endl;
	cout << foo({.p1 = 4}) << endl;
	//cout << foo({.p3 = 5.0}) << endl;
	return 0;
}

Komunikat:

<source>:29:26: error: could not convert '{"aa"}' from '<brace-enclosed initializer list>' to 'Params'

Ostatnia linia nie działa pod C++14:

prog.cpp:31:25: sorry, unimplemented: non-trivial designated initializers not supported

https://ideone.com/AklGBM

1

To, czego używasz to designated initializers z C99, zapewne częściowo dostępne w gcc przez domyślną kompilację w trybie gnu++ (to nie jest C++). Dlaczego nie działa - nie wiem, ale zakładałbym, że nie została ustalona kolejność i sposób inicjalizacji zaawansowanych typów. edit: to też zdaje się potwierdzać komunikat błędu.

Rozważałeś może https://www.boost.org/doc/libs/1_67_0/libs/parameter/doc/html/index.html ?

0

Tnx, Boost::Parameter nie próbowałem, może spróbuję, ale wygląda na bardziej skomplikowane rozwiązanie.

0

Wczoraj nawet wspomniałem o tym na moim mikroblogu. Designated initializers mają się pojawić w C++20 - proposal.

1
several napisał(a):

Wczoraj nawet wspomniałem o tym na moim mikroblogu. Designated initializers mają się pojawić w C++20 - proposal.

Nie widziałem, ale to pozwoliło mi wygenerować mniej-więcej działającą wersję (GCC trunk na godbolt):


int main() {
	cout << foo({2}) << endl;
	cout << foo({.p1 = 4}) << endl;
	cout << foo({.p1 = 3, .p2 = "aa"}) << endl;
	cout << foo({.p1 = 3, .p2 = "aa", .p3 = 3.1}) << endl;
	cout << foo({.p1 = {}, .p2 = "aa"}) << endl;
	cout << foo({.p3 = 5.0}) << endl;
	return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1