2017-12-16 4 views
0

In meinem Code verwende ich etwas wie folgt aus:Was sollte ich anstelle von Vorlagen verwenden?

enum { 
    foo = sizeof(some_type_t) < 32 ? 1 : 2, 
    bar = some_constexpr_function() - N, 
    baz = foo + bar, 
    // etc. 
} 

für eine Reihe von Kompilierung-Konstanten, für die ich dort sicherstellen wollen, wird keine Laufzeitspeicher sein; und ich habe ein paar Funktionen, die diese Konstanten verwenden. N ist eine Konstante, die wir von woanders bekommen.

Nun möchte ich meinen Code nehmen und ihn templatisieren: N ist keine globale Konstante mehr, sondern ein numerischer Template-Parameter. Nun, wenn ich das tat:

template <size_t N> f() 
{ 
    enum { 
     foo = sizeof(some_type_t) < 32 ? 1 : 2, 
     bar = some_constexpr_function() - N, 
     baz = foo + bar, 
     // etc. 
    } 
} 

Das würde funktionieren; aber - es beschränkt mich darauf, diese Konstanten in einer einzigen Funktion zu verwenden; Ich möchte mehrere haben. In C++ können wir nicht haben

template <size_t N> 
    enum { 
     foo = sizeof(some_type_t) < 32 ? 1 : 2, 
     bar = some_constexpr_function() - N, 
     baz = foo + bar, 
     // etc. 
    } 

Was würde eine elegante, oder vielleicht die idiomatische, Art und Weise das Äquivalent dieser templatization zu erreichen?

+0

Wie erwarten Sie auch diese mit anonymen enum arbeiten – Sopel

+0

ich einige [ähnliche Sachen] getan haben (https://gist.github.com/makulik/7963331) einmal. – user0042

+0

Ich verstehe nicht wirklich, was ist der Punkt des Zählers hier. Definieren Sie einfach normale Konstanten. Der Ausdruck "Ich möchte nicht, dass es einen Laufzeitspeicher für" gibt, ist etwas seltsam, denn wenn Sie sie für einige Laufzeitberechnungen verwenden, werden sie höchstwahrscheinlich nach Wert kopiert. – VTT

Antwort

1

Was ich tue, so weit meine Enum in einer Dummy-Halter-Klasse setzt, die kann Templat werden:

template <size_t N> 
struct params 
{ 
    enum { 
     foo = sizeof(some_type_t) < 32 ? 1 : 2, 
     bar = some_constexpr_function() - N, 
     baz = foo + bar, 
    }; 
} 

Aber dann habe ich params::foo, schreiben params::bar überall, das mühsam ist:

do_stuff_with(params::foo, params::bar) 

statt

do_stuff_with(foo, bar); 
4

Genau wie Sie in den Kommentaren gesagt wurden, sehe ich keinen Punkt darauf, diese benannten Konstanten unter einem Enum zu haben. Haben Sie einfach eine Reihe von constexpr Variablen in einem einzigen Namespace-Bereich. Sie können den gleichen Netto-Effekt erhalten:

namespace constants { 
    namespace detail { 
       using underlying_t = int; 
    } 
    template<size_t N> 
    constexpr detail::underlying_t foo = sizeof(some_type_t) < 32 ? 1 : 2; 

    template<size_t N> 
    constexpr detail::underlying_t bar = some_constexpr_function() - N; 

    template<size_t N> 
    constexpr detail::underlying_t baz = foo<N> + bar<N>; 
} 

Sie sind alle constexpr, so dass sie leicht Zeitkonstanten laufen, und Sie können den zugrunde liegenden Typ in einem einzigen Ort steuern, wenn Sie benötigen. Sie können auch entweder mit einer vollständig qualifizierten ID auf sie zugreifen oder sie alle mit einer using-Direktive einbinden.

+0

Diese haben wahrscheinlich Laufzeitspeicher. Ich möchte das vermeiden. – einpoklum

+3

@einpoklum - Sie sind falsch informiert. – StoryTeller

+0

Können Sie mich mit einem Link aufklären? – einpoklum

0

Vielleicht überladen Komma constexprly würde Ihren Bedürfnissen entsprechen?

#include <utility> 

enum params { 
    foo = 1, 
    bar = 2, 
    baz = 3 
}; 


struct some_type_t { }; 
constexpr std::size_t some_constexpr_function() { 
    return 0; 
} 


constexpr std::size_t operator ,(params P, std::size_t N) { 
    switch (P) { 
     case foo: 
      return sizeof(some_type_t) < 32 ? 1 : 2; 
     case bar: 
      return some_constexpr_function() - N; 
     case baz: 
      return (foo, N) - (bar, N); 
    } 
    return 0; 
} 


template <std::size_t> 
struct example { }; 

int main() { 
    example<(baz, 2)>{}; 
} 

[live demo]

+0

Danke für die Idee. Ich finde das Vorhandensein von vielen offenen Klammern - close-Klammern etwas verwirrend. – einpoklum

+0

@einpoklum Wie wäre es mit [Überladen von Komma] (https://wandbox.org/permlink/iPtub0EbRdNr07eA)? :) –

+0

Kudos für Originalität, aber - das bedeutet keine Chance der automatischen Vorlage Parameterauflösung in Funktionen bereits auf N Templated. Und das ist, wenn wir die Hölle für Leute, die verstehen wollen, was los ist ... – einpoklum

Verwandte Themen