gpt4 book ai didi

c++ - 在流畅的界面中避免不必要的模板实例化

转载 作者:太空宇宙 更新时间:2023-11-04 12:13:38 24 4
gpt4 key购买 nike

我有一个带有一些可选模板参数的类:

struct option1_default_t {};
struct option2_default_t {};

template <typename T,
typename option1_t = option1_default_t,
typename option2_t = option2_default_t>
class foo
{
public:
foo(option1_t option1 = option1_t(), option2_t option2 = option2_t());

void run();
};

以及以下fluent interface用于指定它们:

template <typename T, typename option1_t, typename option2_t>
struct foo_runner
{
option1_t option1_;
option2_t option2_;

template <typename new_option1_t>
foo_runner<T, new_option1_t, option2_t> option1(new_option1_t new_option1)
{
return foo_runner<T, new_option1_t, option2_t>{new_option1, option2_};
}

template <typename new_option2_t>
foo_runner<T, option1_t, new_option2_t> option2(new_option2_t new_option2)
{
return foo_runner<T, option1_t, new_option2_t>{option1_, new_option2};
}

void run()
{
foo<T, option1_t, option2_t> f(option1_, option2_);
f.run();
}
};

template <typename T>
foo_runner<T, option1_default_t, option2_default_t> make_foo()
{
return foo_runner<T, option1_default_t, option2_default_t>();
}

下面是如何使用流畅界面的示例:

struct my_option1_t { ... };
struct my_option2_t { ... };

int main()
{
make_foo<int>()
.option1(my_option1_t(...))
.option2(my_option2_t(...))
.run();
}

这当然是简化版;在我的实际代码中有很多选项,在此类的典型使用中,只指定了其中的几个选项,因此有理由使用流畅的界面。

这种流畅界面的问题在于它会引发不必要的模板实例化。例如,上面的例子实例化了foo三遍:foo<int, option1_default_t, option2_default_t> , foo<int, my_option1_t, option2_default_t> ,最后,foo<int, my_option1_t, my_option2_t> ,这就是我想要的。

这是有问题的,因为 foo是一个大类,实例化它的编译时间很昂贵。

有没有一种方法可以改变流畅界面的实现而不改变界面的使用方式,这样foo只实例化一次,带有最后的参数?

请注意,界面不变的要求 - 即我作为使用流畅界面的示例给出的完全相同的代码继续保持不变 - 是这里的关键。如果没有这个要求,我可以很容易地重写流畅的界面来只实例化 foo一次(例如,我可以将界面更改为类似 run_foo(make_foo<int>().option1(...).option2(...)) 的形式)。

最佳答案

我不认为 foo 有多个实例化(正如 MSalters 在评论中指出的那样)。如果你想验证这一点,你可以为默认参数创建 foo 的特化,这会在它们被实例化时导致错误。显然,这对实际生产版本不利,但这将证明没有多个实例化。

一旦您确认 foo 的多个实例化确实不是问题,问题就变成了:如何改进模板代码的编译时间?对此的答案通常是将代码分解为依赖较少模板参数(如果有的话)的助手。这有点痛苦,但会产生巨大的影响。避免在常用模板的所有翻译单元中实例化也可能是有益的。在 C++2011 中,您可以结合使用外部模板和显式实例化。使用 C++2003,您必须专门化要预实例化的代码。

关于c++ - 在流畅的界面中避免不必要的模板实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8696622/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com