2017-09-14 1 views
1

Ich wollte eine Template-Funktion in einem anonymen Namespace einer cpp-Datei haben, rein als Hilfsfunktion für std :: array-Typen unterschiedlicher Größe. Diese Funktion darf außerhalb dieser Übersetzungseinheit nicht verwendet werden.Ist es richtig, eine Template-Funktion in einem anonymen Namespace einer cpp-Datei zu haben?

Ganz überraschend für mich, arbeitete diese sofort aus, wenn ich es in MSVC versuchte 14.1 (vereinfachte Code):

namespace 
{ 

template<std::size_t SIZE> 
bool isPushed(std::uint32_t id, std::array<std::uint32_t, SIZE>& states) 
{ 
    if(id >= states.size()) 
    { 
     return false; 
    } 

    return ((states[id] & 32U) > 0U); 
} 

} 

dies den C++ Standard entspricht?

Von dem, was ich wusste, müssen Vorlagen immer deklariert werden (und oft auch implementiert) in einem Header, warum nicht in diesem Fall?

Antwort

4

Entspricht dies dem C++ - Standard?

Absolut.

Von dem, was ich wusste, müssen Vorlagen immer deklariert werden (und oft auch implementiert) in einem Header, warum nicht in diesem Fall?

Das trifft meistens nur zu, wenn die Vorlage in mehreren Übersetzungseinheiten verwendet wird (gelesene .cpp-Dateien). Es gibt Möglichkeiten, Vorlagen in CPP-Dateien mit extern template zu implementieren. Siehe https://msdn.microsoft.com/en-us/library/by56e477.aspx.

Wenn es jedoch nur in einer .cpp-Datei verwendet wird, ist es vollkommen in Ordnung, es in der CPP-Datei zu definieren.


Zusätzliche Informationen als Antwort auf OP Kommentar

Von https://timsong-cpp.github.io/cppwp/n3337/temp#4

einen Vorlagennamen hat Verknüpfung.

Von https://timsong-cpp.github.io/cppwp/n3337/basic.link#2.2

- Wenn ein Name interne Bindung hat es das Unternehmen bezeichnet kann von anderen Bereichen in derselben Übersetzungseinheit mit Namen bezeichnet werden.

Von https://timsong-cpp.github.io/cppwp/n3337/basic.link#4

Ein ungenannter Namespace oder ein Namensraum direkt oder indirekt innerhalb eines ungenannten Namensraum hat interne Bindung erklärt. Alle anderen Namespaces haben eine externe Verknüpfung. Ein Name mit Namespace-Bereich, der interne Bindung oben nicht gegeben hat, hat die gleiche Bindung wie das umschließende Namespace, wenn es der Name

... ist

- eine Vorlage.

Aus dem obigen können wir schließen, dass isPushed interne Verknüpfung hat.Es kann nur in der Übersetzungseinheit referenziert werden.

+1

Auch wenn es in mehreren Übersetzungseinheiten verwendet wird, gibt es Möglichkeiten, sie manchmal in cpp-Dateien mit 'extern template' zu ​​implementieren. https://msdn.microsoft.com/en-us/library/by56e477.aspx –

+0

@ r-sahu Haben Sie ein Zitat/Verweis auf den C++ - Standard, wo dies beschrieben ist? Wäre großartig. – Ident

+0

@Ident, ich weiß nicht, dass der Standard speziell über diese Situation spricht. Ich werde ein bisschen graben, um zu sehen, ob ich etwas Relevantes finden kann. –

Verwandte Themen