Meine Frage in C zu wählen sind eine Erweiterung dieser Frage: How to use sfinae for selecting constructors?Wie SFINAE verwendet Konstruktor von mehreren Optionen ++ 11
In der vorherige Frage, die Fragesteller nur einen einzigen Konstruktor selektiv aktivieren wollte. Ich möchte das Verhalten des Konstruktors abhängig davon ändern, ob der Klassenschabloneparametertyp standardmäßig-constructible ist - der beste Weg, den ich dazu finden kann, ist zwei Konstruktoren mit der gleichen Verwendung zu haben, so dass genau einer aktiviert ist für jede Instantiierung. Mein Fall ist auch anders, weil keine Version des Konstruktors eine Template-Funktion wäre, wenn ich nicht versuchen würde, selektiv mit enable_if
zu aktivieren (während in der verknüpften Frage beide Versionen des Konstruktors auf int otherN
gestempelt sind).
Die Kommentare in der akzeptierten Antwort auf die obige Frage führten mich zu this site, was mich dazu gebracht, das folgende minimal Beispiel zu erstellen:
#include <iostream>
#include <type_traits>
namespace detail {
enum class enabler {};
enum class disabler {};
}
template <typename Condition>
using EnableIf = typename std::enable_if<Condition::value, detail::enabler>::type;
template <typename Condition>
using DisableIf = typename std::enable_if<!Condition::value, detail::disabler>::type;
template<typename T>
struct A {
T data;
// Valid if T is default-construtible; SFINAE otherwise
template<EnableIf<std::is_default_constructible<T>>...>
A() { std::cout << "Data defaulted" << std::endl; }
// Valid if T is *not* default-constructible; SFINAE otherwise
template<DisableIf<std::is_default_constructible<T>>...>
A() : data(0) { std::cout << "Data zeroed" << std::endl; }
};
// struct which is not default-constructible
struct B {
B() = delete;
B(int) {}
};
int main()
{
A<int> x; // int is default-constructible
A<B> y; // class B is not default-constructible
return 0;
}
Das kann ich kompilieren (mit -std=c++11
), wenn ich den ersten Kommentar aus Konstruktor und die Deklaration von x oder dem zweiten Konstruktor und die Deklaration von y. Ich möchte beides nicht tun, aber wenn ich versuche, dass der Compiler beschwert, dass es keinen type
in std::enable_if<false, >
genannten Typ gibt.
Die Antworten auf this Frage nehmen einen anderen Ansatz zu einem ähnlichen Problem, aber ich verstehe die Faktoren im Spiel nicht gut genug, um in der Lage zu sein, die Ansätze in etwas zu kombinieren, das funktioniert.
[fast statisch-if] (https://rmf.io/cxx11/almost-static-if) Link muss aktualisiert werden. (kein abschließender Schrägstrich) – tukra
Korrigiert, danke – user1476176