我正在 C++ 17 中处理 DDD 值对象,所以一切都是 const/constexpr ,工作得很好。有以下两个类:
class JD final
{
public:
constexpr explicit JD(const unsigned long jd) noexcept
: jd(jd)
{
}
[[nodiscard]] constexpr unsigned long getJD() const noexcept
{
return(this->jd);
}
private:
const unsigned long jd;
};
class MJD final
{
public:
constexpr explicit MJD(const unsigned long mjd) noexcept
: mjd(mjd)
{
}
constexpr explicit MJD(const JD &jd)
: mjd(convertJD2MJD(jd))
{
}
private:
const unsigned long mjd;
constexpr unsigned long convertJD2MJD(const JD &jd) const
{
if (jd.getJD() < 2400001UL)
{
throw std::out_of_range("JD must be >= 2400001");
}
return (jd.getJD() - 2400001UL);
}
};
这按预期工作。但我想用 lambda 替换私有方法:
constexpr explicit MJD(const JD &jd)
: mjd([](const JD &jd) constexpr -> const unsigned long {if (jd.getJD() < 2400001UL) {throw std::out_of_range("JD must be >= 2400001");} return (jd.getJD() - 2400001UL);})
{
}
但这会导致:
error: no viable conversion from '(lambda at ...' to 'const unsigned long'
: mjd([](const JD &jd) constexpr -> const unsigned long {if (jd.getJD() < 2400001UL) {throw std::out_of_range("JD must be >= 2400001");} return (jd.getJD() - 2400001UL);})
我已经给出了“constexpr -> const unsigned long”,这没有什么区别。
Windows 10 上的编译器是 clang 版本 17.0.1。
所以我的问题是如果可能的话如何实现这项工作?如果不是,我错过了什么,因为私有方法按预期工作?
当前您正在尝试使用 lambda 对象本身来初始化
mjd
,而不是使用 lambda 的返回值来初始化它。也就是说,您需要调用 lambda 并使用其返回值作为 mjd
的初始化器,如下所示:
constexpr explicit MJD(const JD &jd)
: mjd([](const JD &jd) constexpr -> unsigned long {if (jd.getJD() < 2400001UL)
{
throw std::out_of_range("JD must be >= 2400001");
}
//-------------------------------vvvv----->explicitly call the lambda and pass jd
return (jd.getJD() - 2400001UL);}(jd))
{
}
感谢@G.M.解决方案很简单,因为我错过了添加参数来调用 lambda:
constexpr explicit MJD(const JD &jd)
: mjd([](const JD &jd) constexpr -> const unsigned long {if (jd.getJD() < 2400001UL) {throw std::out_of_range("JD must be >= 2400001");} return (jd.getJD() - 2400001UL);}(jd))
{
}