edit这是不是重复的 of 对静态类成员的未定义引用 https://stackoverflow.com/questions/272900/undefined-reference-to-static-class-member。这个问题探讨了cause问题的根源(我将在下面解释)。在这里,我正在寻找一个不同的解决方案从对这些问题的回答中提出的建议(这意味着改变声明/定义constexpr
要使用的变量——本质上是通过在编译单元中添加定义来实现的)。
我创建了一个小的可变参数模板函数make_string()
生成一个std::string
来自任意数量的 io-able 参数,如下所示。
using std::ostringstream; // just for this example
inline ostringstream&write(ostringstream&ostr, const char*x)
{ if(x) ostr<<x; return ostr; }
template<class T>
inline ostringstream&write(ostringstream&ostr, T const&x)
{ ostr<<x; return ostr; }
inline ostringstream&write(ostringstream&ostr) noexcept
{ return ostr; }
template<class T, class... R>
inline ostringstream&write(ostringstream&ostr, T const&x, R&&... r)
{ return write(write(ostr,x), std::forward<R>(r)...); }
inline std::string make_string(const char*text)
{ return {text?text:""}; }
inline std::string make_string(std::string const&text)
{ return {text}; }
template<typename T>
inline auto make_string(T var) -> decltype(std::to_string(var))
{ return std::to_string(var); }
template<class... Args>
inline std::string make_string(Args&&... args)
{
ostringstream ostr;
write(ostr,std::forward<Args>(args)...);
return std::move(ostr.str());
}
现在,这工作得很好,可以像这样使用
throw std::runtime_error(make_string("offset=",offset," > max_offset =",
max_offset"));
但是打印的时候出现问题static constexpr
班级成员,如
class foo
{
static constexpr int max_offset=some_value;
// ...
void bar(int offset)
{
if(offset > max_offset)
throw std::runtime_error(make_string("offset=",offset," > max_offset=",
max_offset"));
}
};
这会导致链接时出现错误。原因是make_string
通过引用获取其所有参数,包括static constexpr
max_offset
。结果,参考foo::max_offset
链接时需要,see also https://stackoverflow.com/questions/272900/undefined-reference-to-static-class-member.
我怎样才能避免这个问题而不放弃这个想法make_string()
? (也许可以用可变参数宏替换可变参数模板,但我认为这是某种回归。)必须有一种方法让 make_string 根据类型通过值或引用获取其参数(以便内置类型可以按值取)。如何?