【发布时间】:2011-08-10 05:10:21
【问题描述】:
假设我有一个函数,它将函数指针作为参数,并且该参数有一个默认参数。
template <typename T>
T* default_construct()
{
return new T();
}
template <typename T>
void register(T* (*construct)() = default_construct<T>)
{
// Save that function pointer for later
}
假设我想在我的班级 Foo 上使用 register,但 Foo 没有默认构造函数,所以我的 default_construct 将无法使用它。显而易见的解决方案是这样做:
Foo* construct_Foo()
{
return new Foo("String argument", 123);
}
SomeFunc()
{
// ...
register<Foo>(construct_Foo);
// ...
}
但这不起作用。即使register<Foo> 只能在一个地方调用,并且它传递了一个要使用的函数,default_construct<Foo> 仍然被编译器实例化,并且我得到编译器错误。似乎因为它从未被使用过,所以应该跳过它,但我想事实并非如此。
当default_construct 被用作默认参数时,有什么方法可以防止它被实例化?我能想到的唯一解决方案是将它放在模板中,但似乎应该有更好的解决方案。
【问题讨论】:
-
你确定 default_construct 被实例化了吗?老实说,我认为默认参数只有在使用时才会被实例化。以下通过了我尝试过的所有编译器:ideone.com/lHfSf
-
在 UncleBens 之后,您可以检查库/可执行文件的符号以检查函数模板是否已被实例化。即使名称已损坏,
default_construct仍应出现。使用nm somelib | grep default_construct并在结果符号上使用c++filt以获得扩展版本。 -
UncleBens:你也许是对的。我肯定收到了一个似乎是由错误的模板实例化引起的错误,但我只是再次尝试向您显示错误消息,而这次我没有收到。我一定做错了什么,也许这整个问题是没有实际意义的。诡异的。 (FWIW,我正在使用 gcc)
标签: c++ templates default-arguments