我在" extern"上发出了各种问题和评论。模板声明以及如何通过明确告诉编译器不要在转换单元中实例化某个模板类或函数来减少编译时间。
但是,我无法将这些外部声明与GCC 8.1.0一起使用。
我创建的示例基本上是一个元组打印机,std :: couts 512元素元组的所有元素。 for_each实现对每个元素使用泛型函数调用,在SO上可以找到多个版本。
test.hpp
#include <iostream>
#include <tuple>
#include "for_each.hpp"
constexpr auto t = std::tuple{ 0, ..., 511};
template<typename T>
struct Test {
void print() {
for_each(t, [](auto v) { std::cout << v << "\n"; });
}
};
TEST.CPP
#include "test.hpp"
template class Test<int>;
多个源文件现在创建一个Test&lt;的实例。 int&gt;并使用打印功能。
src0.cpp
#include "test.hpp"
extern template class Test<int>;
void src0() {
Test<int> t;
t.print();
}
据我所知,测试&lt; int&gt;现在它的print函数只能由test.cpp创建一次,而不能由src0.cpp或其他源文件创建,并将模板声明为extern。然而,那不是发生的事情。我添加的每个源文件都使用Test&lt; int&gt;另一个实例化发生......由于GCC倾向于为创建函数调用和类型/(lambdas)分配大量内存,因此这非常繁琐且耗时。下面是使用Test&lt;编译三个源文件时机器内存消耗的图片。 int&gt; ...
我在这里遗漏了什么?我认为那确实是什么&#34; extern模板&#34;应该用于?
for_each实现完成:
for_each.hpp
#pragma once
#include <tuple>
namespace detail {
template<typename T, typename F, size_t... Is>
constexpr void for_each_impl(T&& t,
F&& f,
std::integer_sequence<size_t, Is...>) {
(f(std::get<Is>(std::forward<T>(t))), ...);
}
} // namespace detail
template<typename T, typename F>
constexpr void for_each(T&& t, F&& f) {
detail::for_each_impl(std::forward<T>(t),
std::forward<F>(f),
std::make_index_sequence<
std::tuple_size_v<std::remove_reference_t<T>>>{});
}