Überprüfen Sie die Eigenschaften aller variablen Vorlagenargumente
Hintergrund Ich habe die folgende Klasse erstelltC
, dessen Konstruktor @ nehmen soN
Variablen vom TypB&
:
class A;
class B
{
A* getA();
};
template<size_t N>
class C
{
public:
template<typename... Args>
inline C(Args&... args) :
member{args.getA()...}
{}
private:
std::array<A*, N> member;
};
Problem mein Problem ist, wie man die variadic @ einschränArgs
um alle vom Typ @ zu seB
?
Meine Teillösung: Ich wollte ein Prädikat definieren wie:
template <typename T, size_t N, typename... Args>
struct is_range_of :
std::true_type // if Args is N copies of T
std::false_type // otherwise
{};
Und definiere meinen Konstruktor entsprechend neu:
template <typename... Args,
typename = typename std::enable_if<is_range_of_<B, N, Args...>::value>::type
>
inline C(Args&... args);
Ich habe eine mögliche Lösung für diesen Beitrag gesehen:https: //stackoverflow.com/a/1141463, das ein generisches @ definiecheck_all
Prädikat:
template <template<typename> class Trait, typename... Args>
struct check_all :
std::false_type
{};
template <template<typename> class Trait>
struct check_all<Trait> :
std::true_type
{};
template <template<typename> class Trait, typename T, typename... Args>
struct check_all<Trait, T, Args...> :
std::integral_constant<bool, Trait<T>::value && check_all<Trait, Args...>::value>
{};
Also, ich könnte so etwas schreiben:
template <typename T, size_t N, typename... Args>
struct is_range_of :
std::integral_constant<bool,
sizeof...(Args) == N &&
check_all<Trait, Args...>::value
>
{};
Frage 1 Ich weiß nicht, wie ich das @ definieren soTrait
, weil ich irgendwie binden mussstd::is_same
mitB
als erstes Argument. Gibt es eine Möglichkeit, das generische @ zu verwendecheck_all
in meinem Fall, oder ist die aktuelle Grammatik von C ++ nicht kompatibel?
Frage 2 Mein Konstruktor sollte auch abgeleitete Klassen von @ akzeptiereB
(durch einen Verweis aufB
), ist das ein Problem bei der Ableitung von Vorlagenargumenten? Ich fürchte, wenn ich ein Prädikat wie @ benutstd::is_base_of
, Ich erhalte für jeden Parametersatz eine andere Instanziierung des Konstruktors, wodurch der kompilierte Code vergrößert werden könnte ...
Bearbeiten: Zum Beispiel habe ichB1
undB2
das erbt vonB
, Ich rufeC<2>(b1, b1)
undC<2>(b1, b2)
Wird es in meinem Code zwei Instanzen (von @) erstelleC<2>::C<B1, B1>
undC<2>::C<B1, B2>
)? Ich möchte nur Instanzen vonC<2>::C<B, B>
.