【问题标题】:Preventing instantiation of unused default function arguments防止实例化未使用的默认函数参数
【发布时间】: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&lt;Foo&gt; 只能在一个地方调用,并且它传递了一个要使用的函数,default_construct&lt;Foo&gt; 仍然被编译器实例化,并且我得到编译器错误。似乎因为它从未被使用过,所以应该跳过它,但我想事实并非如此。

default_construct 被用作默认参数时,有什么方法可以防止它被实例化?我能想到的唯一解决方案是将它放在模板中,但似乎应该有更好的解决方案。

【问题讨论】:

  • 你确定 default_construct 被实例化了吗?老实说,我认为默认参数只有在使用时才会被实例化。以下通过了我尝试过的所有编译器:ideone.com/lHfSf
  • 在 UncleBens 之后,您可以检查库/可执行文件的符号以检查函数模板是否已被实例化。即使名称已损坏,default_construct 仍应出现。使用nm somelib | grep default_construct 并在结果符号上使用c++filt 以获得扩展版本。
  • UncleBens:你也许是对的。我肯定收到了一个似乎是由错误的模板实例化引起的错误,但我只是再次尝试向您显示错误消息,而这次我没有收到。我一定做错了什么,也许这整个问题是没有实际意义的。诡异的。 (FWIW,我正在使用 gcc)

标签: c++ templates default-arguments


【解决方案1】:

这是解决问题的一种解决方案,因为它不使用默认参数:

template <typename T>
T* default_construct()
{
    return new T();
}

template <typename T>
void register(T* (*construct)())
{
    // Save that function pointer for later
}

template<typename T>
void register()
{
    register<T>(default_construct<T>);
}

请注意,register 是一个 C++ 关键字:)

【讨论】:

  • 哇!这只是一个例子:P 实际的函数是 luaW_register,但我不想把 Lua 拉到我的问题中。
  • @Alex 每当默认参数发挥作用时,请记住它们只是函数重载的快捷方式,任何可以通过默认参数完成的事情以及更多都可以通过重载来完成。和 lua 一起玩,太棒了
  • 我真的没有这么想过,但我想你是对的。如果您有兴趣,这是我尝试改进我正在编写的this little Lua/c++ 库的一部分。
  • @Alex 酷,你做了哪些改进?是的,我讨厌在没有像这样的包装器的情况下使用 lua。
  • @Alex 哦,你写的。我以为你在改进别人的包装器(没有意识到你是同一个亚历克斯)。那有一个书签,我下次使用lua时肯定会使用它。干得好。
猜你喜欢
  • 1970-01-01
  • 2020-07-10
  • 2013-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-29
相关资源
最近更新 更多