Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it proper to have a template function inside an anonymous namespace of a cpp file?

Tags:

c++

I wanted to have a template function inside an anonymous namespace of a cpp file, purely as a helper function for std::array types of different sizes. This function is not to be used anywhere outside this translation unit.

Quite surprisingly to me, this worked out right away when I tried it in MSVC 14.1 (simplified 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);
}

}

Does this conform to the C++ standard?

From what I had known, templates always need to be declared (and often also implemented) in a header, why not in this case?

like image 996
Ident Avatar asked Sep 14 '17 22:09

Ident


1 Answers

Does this conform to the C++ standard?

Absolutely.

From what I had known, templates always need to be declared (and often also implemented) in a header, why not in this case?

That is mostly true only if the template is used in multiple translation units (read .cpp files). There are ways to implement templates in .cpp files using extern template. See https://msdn.microsoft.com/en-us/library/by56e477.aspx.

However, when it is used only in one .cpp file, it is perfectly fine to define it in the .cpp file.


Additional info, in response to OP's comment

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

A template name has linkage.

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

— When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in the same translation unit.

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

An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage. A name having namespace scope that has not been given internal linkage above has the same linkage as the enclosing namespace if it is the name of

...

— a template.

From the above, we can conclude that isPushed has internal linkage. It can be referred to only in the translation unit.

like image 125
R Sahu Avatar answered Nov 10 '22 16:11

R Sahu