Um ähnliche Funktionsdefinitionen zu wiederholen, verwende ich die Tatsache, dass die Mitglieder mit dem gleichen Namen vererbt werden versteckt und können ausgewählt werden/differenziert durch eine bestimmte Basisklasse-Qualifikation mit:Wie kann ich noexcept verwenden, wenn ich eine bestimmte versteckte Funktion aus meiner Vererbungsliste auswähle?
#include <type_traits>
template<template<class, class> class CreatePolicy, class Base, class... Derived>
class factory : public CreatePolicy<Base, Derived>...
{
public:
template
<
class T,
std::enable_if_t
<
!std::is_same<Base, T>::value && std::is_base_of<Base, T>::value, int
> = 0
>
std::unique_ptr<Base> create() noexcept(noexcept(CreatePolicy<Base, T>::create()))
{
return CreatePolicy<Base, T>::create();
}
};
Mit ihm sieht wie folgt aus :
#include <memory>
#include <cassert>
template<class Base, class Derived>
struct create_t
{
auto create()
{
return std::make_unique<Derived>();
}
};
struct base
{
virtual void print() const noexcept
{
std::cout << "base\n";
}
};
struct derived : public base
{
virtual void print() const noexcept override
{
std::cout << "derived\n";
}
};
int main()
{
factory<create_t, base, derived> f;
auto d = f.create<derived>();
d->print();
}
Während dies unter 2015 VC++ kompiliert wird GCC5.1 mir diesen Fehler geben aufgrund der noexcept
Spezifikation von create()
:
..\main.cpp|20|error: cannot call member function 'auto create_t<T>::create() [with T = derived]' without object|
Wie kann ich dies kompilieren?
Gibt es einen Grund, warum dies von GCC andere als abgelehnt wird, dass er einen Fehler hat? Es sieht wie gültiges C++ aus. Bei der Instantiierung sollte es in einen impliziten Klassenmember-Zugriff umgewandelt werden. –
@joha Ich weiß keinen Grund, warum ein implizites 'this->' in diesem Kontext angenommen würde. Das passiert normalerweise nur in Körpern von Mitgliedsfunktionen. MSVC Template Instanziierungscode ist ziemlich skurril und nicht konform, also würde ich annehmen, dass sie wie gewöhnlich vermasselt sind. – Yakk
Das Implizite Dies sollte hinzugefügt werden, wo auch immer "this" verwendet werden kann, und es sollte hinzugefügt werden, wenn die Vorlage im Instanziierungskontext instanziiert wird (Nachschlagen, da dieses Teil in letzter Zeit aufgrund von Defekten häufig geändert wurde). Also ein implizites sollte hier IMHO hinzugefügt werden. Die Transformation findet in allen "members" (auch NSDMIs) statt, also auch in excepts, da "this" dort verwendet werden kann und der Code zu diesem Zeitpunkt gültig ist, so dass der Compiler ihn zur Template-Definitionszeit nicht ablehnen kann. IMHO OPs Code ist gültig. –