我有一个将配置结构作为参数的函数
struct Config
{
Config(); //<-- default constructor
// some configuration constants
};
int computeSomethingFrom(Something arg, const Config& config = Config());
Config()
和computeSomethingFrom(...)
的定义都在同一个源文件中。
我的猜测是,每个函数调用都将被强制构造Config
,因为无法知道默认构造函数是否依赖于环境中的其他内容。如果配置结构变大或函数被多次调用,这可能会变得昂贵。
不过,如果可以的话,我宁愿避免创建另一个常量。并且可能,因为默认构造函数和函数是在同一个源文件中定义的,因此编译器可以推断Config()
总是返回相同的东西。
那么有什么方法可以避免做类似的事情
inline Config DEFAULT_CONFIG = Config();
,然后将该函数声明为
int computeSomethingFrom(Something arg, const Config& config = DEFAULT_CONFIG);
?
答案 0 :(得分:6)
只需重载此功能:
int computeSomethingFrom(Something arg, const Config& config); // note no default value
int computeSomethingFrom(Something arg);
我不知道这会如何影响您的代码,因为您没有提供任何信息computeSomethingFrom
。
一种可能的实现方式(可能您对此不会满意):
int computeSomethingFrom(Something arg)
{
static const Config cfg;
return computeSomethingFrom(arg, cfg);
}
答案 1 :(得分:3)
那么有什么方法可以避免做类似的事情
inline Config DEFAULT_CONFIG = Config();
,然后将该函数声明为
int computeSomethingFrom(Something arg, const Config& config = DEFAULT_CONFIG);
您确实可以声明全局(在文件范围内)并使用:
/*static*/ const Config DEFAULT_CONFIG = Config();
int computeSomethingFrom(Something arg, const Config& config = DEFAULT_CONFIG);
即使您不需要它,也将在“开始”时调用构造函数一次(与其他全局变量一样)。
您可能会这样创建一个“惰性”工厂:
const Config& DefaultConfig() {
static Config config; // Call only once
return config;
}
int computeSomethingFrom(Something arg, const Config& config = DefaultConfig());
主要与其他带有重载的提案一样
int computeSomethingFrom(Something arg, const Config& config);
int computeSomethingFrom(Something arg)
{
static const Config config;
return computeSomethingFrom(arg, config);
}
但处理同一功能的多个默认参数,
并为多个功能处理相同的默认值。
答案 2 :(得分:2)
我的猜测是,每个函数调用都将被强制构造Config,因为无法知道默认构造函数是否依赖于环境中的其他内容。
您会惊讶于任何现代编译器可以做什么。所有空代码将被优化掉。您想要集中更多的可读性,而不是试图猜测编译器。只有对运行的代码进行了性能分析并确定了瓶颈之后,再尝试在那里进行一些优化。
答案 3 :(得分:2)
如果您不想使用默认实例污染全局空间,并且希望避免在每个函数调用中创建对象,那么我建议重载该函数。有一个版本使用Config
,而另一个版本则不需要。然后,在没有创建的static Config
中创建一个实例。由于静态变量需要某种保护以确保它们不会被多次初始化,因此这仍然会有少量的开销。看起来像
int computeSomethingFrom(Something arg, const Config& config)
{
// do the stuff
}
int computeSomethingFrom(Something arg)
{
static Config config{};
computeSomethingFrom(std::move(arg), config);
}