假设我有一个模板函数:
template<typename... Args>
void my_log_function(Args&&... args)
{
// Work, work, work.
}
然后将其调用为:
my_log_function("1");
my_log_function("22");
my_log_function("333");
my_log_function("4444");
my_log_function("55555");
由于字符串文字的类型是const char[n]
,我相信这会创建很多my_log_function
的实例化(Visual Studio Intellisense似乎暗示了这一点)。有没有人认为这是一个问题?是真的吗?可以预防吗?
答案 0 :(得分:2)
是的,这应该创建一个不同的类模板实例。它们应该只是通过引用传递的数组的大小不同,如果它们的数组实际上不再用作数组,则生成的代码应该是相同的。据我所知,VC ++折叠相同的代码。如果类型传播很多,则可能会导致代码膨胀。
防止代码膨胀的一种方法是有条件地衰减类型并转发到另一个执行实际工作的模板。我认为这应该可以解决问题:
template <typename... Args>
void my_real_log_function(Args&&... args) {
// real implementation goes here
}
template <typename T>
struct decay_array {
typedef typename std::condition<
std::is_array<typename std::remove_reference<T>::type>::value,
typename std::decay<T>::type,
T>::type type;
};
template <typename... Args>
void my_log_function(Args&&... args) {
my_real_log_function(std::forward<typename std::decay_array<Args>::type>(args)...);
}
仅使用typename std::decay<T>::type
的原始版本不起作用,因为它会将对非数组的引用转换为非预期的值。
答案 1 :(得分:1)
解决方案不是在这样的功能中实现“工作,工作,工作”。将变量参数清理为更规范的东西,并将工作交给非模板。
注意膨胀并记住模板系统旨在生成内联函数。