
Aart Stuurmann
Ich möchte verwenden constexpr if
zur Kompilierzeit zu verzweigen, scheint aber vom neuesten MSVC-Compiler nicht unterstützt zu werden. Gibt es eine Alternative zu Folgendem?:
template<typename T>
void MyFunc()
{
if constexpr(MeetsConditions<T>::value)
{
FunctionA<T>();
}
else
{
FunctionB<T>();
}
}
Kurzum: Kann ich simulieren constexpr if
wenn es vom Compiler nicht unterstützt wird?

Sternenlicht
Eine der Möglichkeiten vor C++17 ist die Verwendung partieller Template-Spezialisierungen, wie hier:
template <typename T, bool AorB>
struct dummy;
template <typename T, true>
struct dummy {
static void MyFunc() { FunctionA<T>(); }
}
template <typename T, false>
struct dummy {
static void MyFunc() { FunctionB<T>(); }
}
template <typename T>
void Facade() {
dummy<T, MeetsConditions<T>::value>::MyFunc();
}
Wenn Sie mehr als 2 Spezialisierungen benötigen, können Sie Aufzählungen oder ganzzahlige Werte verwenden und Spezialisierungen für alle erforderlichen Aufzählungen vornehmen.
Eine andere Möglichkeit ist die Verwendung von std::enable_if:
template <typename T>
std::enable_if<MeetsConditions<T>::value, void>::type
MyFunc() {
FunctionA<T>();
}
template <typename T>
std::enable_if<!MeetsConditions<T>::value, void>::type
MyFunc() {
FunctionB<T>();
}
Sie können es auf die altmodische und bewährte Weise des Tag-Versands tun:
template<typename T>
void MyFuncImpl(std::true_type) {
FunctionA<T>();
}
template<typename T>
void MyFuncImpl(std::false_type) {
FunctionB<T>();
}
template<typename T>
void MyFunc()
{
MyFuncImpl<T>(std::integral_constant<bool, MeetsConditions<T>::value>{});
}

Justin
Wenn Sie C++ 14 und Boost verwenden, sollten Sie die Verwendung von Hanna. Implementiert mit Hana sieht das etwa so aus:
template<typename T>
void MyFunc()
{
hana::eval_if(MeetsConditions<T>::value,
[](auto) { FunctionA<T>(); },
[](auto _) { FunctionB<T>(_(exprThatWouldOtherwiseBeAnError)); }
);
}
Für den speziellen Fall, SFINAE zu erkennen und nur in diesem Fall etwas auszuführen, könnte das so einfach sein wie:
template<typename T>
void MyFunc()
{
auto maybeDoFunctionA = hana::sfinae([]() -> decltype((void) FunctionA<T>()) {
FunctionA<T>();
});
}
Es gibt in der Tat mehrere Alternativen (die schon lange im Einsatz waren if constexpr
begann zu existieren).
Einer ist der Tag-Versand:
template <class T>
void Function(std::true_type)
{
FunctionA<T>();
}
template <class T>
void Function(std::false_type)
{
FunctionB<T>();
}
template <class T>
void MyFunc()
{
Function<T>(std::integral_constant<bool, MeetsCondition<T>::value>{});
}
Ein weiterer sind Eigenschaften:
template <bool B>
struct FunctionTraits;
template <>
struct FunctionTraits<true>
{
template <class T>
static void Call() { FunctionA<T>(); }
};
template <>
struct FunctionTraits<false>
{
template <class T>
static void Call() { FunctionB<T>(); }
};
template <class T>
void MyFunc()
{
FunctionTraits<MeetsCondition<T>::value>::Call<T>();
}

max66
if constexpr
ist eine C++17-Funktion; vor C++17, ab C++11, können Sie SFINAE mit verwenden std::enable_if
template<typename T>
typename std::enable_if<true == MeetsConditions<T>::value>::type MyFunc ()
{ FunctionA<T>(); }
template<typename T>
typename std::enable_if<false == MeetsConditions<T>::value>::type MyFunc ()
{ FunctionB<T>(); }
— BEARBEITEN —
Wenn Sie nur einen C++98-Compiler verwenden können, implementieren Sie Typeigenschaften, die wie funktionieren std::enable_if
ist wirklich einfach; siehe folgendes Beispiel
template <bool, typename = void>
struct enableIf
{ };
template <typename T>
struct enableIf<true, T>
{ typedef T type; };
und die Funktionen werden
template<typename T>
typename enableIf<true == MeetsConditions<T>::value>::type MyFunc ()
{ FunctionA<T>(); }
template<typename T>
typename enableIf<false == MeetsConditions<T>::value>::type MyFunc ()
{ FunctionB<T>(); }

García Sylvain
Daran bin ich vor kurzem hängengeblieben … Also habe ich ein Tiny erstellt if_constexpr
Bibliothek für die Rückportierung von c++17-Code nach c++14.
#include <if_constexpr.hpp>
template<typename T>
constexpr void MyFunc()
{
using namespace ic;
if_<MeetsConditions<T>::value>([] {
FunctionA<T>();
}, else_([] {
FunctionB<T>();
}));
}
10157700cookie-checkConstexpr falls alternativyes
Es ist eine C++17-Funktion
– max66
24. April 2017 um 11:58 Uhr
Ja, ich weiß, das Problem ist, dass das neueste MSVC C ++ 17 nicht vollständig unterstützt.
– Aart Stuurmann
24. April 2017 um 12:01 Uhr
Könnte interessant sein: statische_wenn-mit-c11c14 simulieren
– Jarod42
24. April 2017 um 12:26 Uhr