Erzwingen Sie eine einschränkende Konvertierungswarnung, vermeiden Sie jedoch eine einschränkende int->double-KonvertierC++

Programme in C++. Entwicklerforum
Anonymous
 Erzwingen Sie eine einschränkende Konvertierungswarnung, vermeiden Sie jedoch eine einschränkende int->double-Konvertier

Post by Anonymous »

Ähnlich dem hier beschriebenen Problem muss ich eine Vorlagenklasse erstellen, die den Konvertierungskonstruktor von jedem Typ bereitstellen soll. Der Konvertierungskonstruktor sollte die einschränkenden Konvertierungen erkennen.

Code: Select all

template
struct X
{
T v_;

// Add conversion constructor here
};
... also wird der folgende Code ohne die Fehler und Warnungen kompiliert:

Code: Select all

// g++ -Wall -Werror -Werror=narrowing ./2.cpp

#include 
#include 

template
void test(X) {}

int main()
{
test(1);
test("1");
}
Die Herausforderung besteht darin, dass ich möchte, dass der Konvertierungskonstruktor bei der Konvertierung int -> double stumm bleibt, wenn die Eingabe ein konstanter Ausdruck ist, wie im C++-Standard beschrieben:

[dcl.init.list]
{7} Eine einschränkende Konvertierung ist eine implizite Konvertierung
7.3) von einem Ganzzahltyp oder einem Aufzählungstyp ohne Gültigkeitsbereich in einen Gleitkommatyp, außer, wenn die Quelle ein konstanter Ausdruck ist und der tatsächliche Wert nach der Konvertierung in den Zieltyp passt und den ursprünglichen Wert erzeugt, wenn er zurück in den ursprünglichen Typ konvertiert wird, oder

Falls ich den Konvertierungskonstruktor wie folgt definiere:

Code: Select all

X(T v) : v_(v) {}
... es funktioniert einfach großartig, wenn T == double, aber es funktioniert nicht, wenn T == string_view und der Eingabeparametertyp char const*
ist

Code: Select all

./2.cpp:26:32: error: could not convert ‘(const char*)"1"’ from ‘const char*’ to ‘X’
26 |         test("1");
Falls ich diesen Konstruktor wie folgt definiere:

Code: Select all

template
X(Other const& v) : v_{v} {}
...es funktioniert hervorragend mit std::string_view, gibt jedoch die einschränkende Konvertierungswarnung aus, wenn T == double und der Typ des Eingabearguments int ist:

Code: Select all

./2.cpp:17:23: error: narrowing conversion of ‘(int)v’ from ‘int’ to ‘double’ [-Werror=narrowing]
17 |   X(Other const& v) : v_{v} {}
|                       ^~~~~
Keine der folgenden Antworten beantwortet meine Frage:
  • Vorlagenabzug und implizite Konstruktoren: Gibt es eine Möglichkeit, den Vorlagenabzug mit impliziter Konvertierung zum Laufen zu bringen?
  • Wie verwende ich die Vorlagenfunktion für die implizite Konvertierung?
  • Eingrenzung der Konvertierung von char nach double
Eine Option, die ich sehe, besteht darin, zwei Konstruktoren zu deklarieren:
  • Einer für den Fall, wenn T ein Gleitkommatyp ist
  • Ein anderer für den Rest der Fälle.
... aber es scheint ein Overkill zu sein.
Eine andere Option besteht darin, einen Konstruktor zu deklarieren und ihn zu aktivieren_if_t, wenn OtherT ohne Datenverlust in T konvertiert werden kann. Ich muss nur mit der Funktion such trait kommen:

Code: Select all

template>
X(Other const& v) : v_(static_cast(v)) {}
In diesem Fall wird ein schwerer Fehler anstelle einer Warnung gemeldet, was in meinem Fall in Ordnung ist.
Gibt es andere Optionen?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post