I don't see C++11 extern templates listed anywhere on
chromium-cpp.appspot.com. Are we allowed to use them? Do we need a formal proposal/discussion thread for them? (Note: "extern templates" are different than "export templates".)
Brief explanation: C++11 extern templates allow you to suppress automatic instantiation of templates by the compiler. E.g., you can have something like:
max.h:
template <typename T> T Max(T a, T b) { return (a > b) ? a : b; }
extern template int Max(int, int);
extern template long Max(long, long);
max.cc:
#include "max.h"
template int Max(int, int);
template long Max(long, long);
Normally if the compiler sees a call to "Max(int, int)" within a compilation unit, it would have to instantiate the template and emit a compiled copy, which the linker is then responsible for duplicate merging. However, if it sees the "extern template" declaration above, it can assume there will be an explicit instantiation in some compilation unit, and can avoid the extra work.
This functionality can be used for templates that have very common instantiations; e.g., libstdc++'s <string> includes "extern template class basic_string<char>;" and "extern template class basic_string<wchar_t>;" because std::string and std::wstring are the most common instantiations of basic_string.
Another use is for hiding unnecessary implementation details. E.g., in sandbox/linux/bpf_dsl, I use the convention of
namespace internal {
class FooImpl : base::RefCounted<FooImpl> { ... };
}
typedef scoped_refptr<const internal::FooImpl> Foo;
and the user facing APIs are focused around passing around Foos as opaque values. However, I currently still need to include the FooImpl definition in the header, even though it's a purely implementation detail.
Using extern templates I could change this to:
namespace internal {
class FooImpl;
extern template class scoped_refptr<const FooImpl>;
}
typedef scoped_refptr<const internal::FooImpl> Foo;
and keep FooImpl's definition hidden from end users. (Technically a few of scoped_refptr's member function definitions would need to be moved out-of-line too.)