【发布时间】:2018-03-08 04:57:13
【问题描述】:
我想使用std::optional 编写一个带有可选参数的模板函数,
template<typename T1, typename T2>
void fcn(T1 v1, std::optional<T2> v2)
{
}
int main()
{
fcn(1, 1); // failed to compile
fcn(1, std::nullopt); // failed as well
}
但是,编译器无法针对这两种情况推导出 T2。
我知道,当 T1 和 T2 相同时,将第二个参数放入不可演绎的上下文中,例如,
template<typename T>
void fcn(T v1,
std::enable_if<true, T>::type v2)
{
}
让调用者可以正常调用fcn(1, 1)。我的第一个问题是如何在不强制调用者写fcn(v1, std::make_optional(v2)) 的情况下为我之前的示例实现这一点?
我的第二个问题是如何使用std::nullopt 调用fcn,而不是编写函数重载?由于在我的用例中可能有几个可选参数,并且编写所有重载排列太不切实际了。
----编辑----
正如 cmets 所建议的,有多种方法可以编译代码,但没有一种方法比普通函数调用更直观。也许还有一个问题要问,编写模板函数接受不同类型的可选参数的正确方法是什么?
【问题讨论】:
-
就像一个注释,这迫使调用者写
fcn<int, int>(1, 1)或fcn<int, int>(1, std::nullopt),这似乎比fcn(v1, std::make_optional(v2))更合理。 -
@YSC 但我认为让调用者提供第二个类型参数仍然不是很直观,尽管她打算省略它。
-
@unclejimbo:如果您对
T2类型的知识毫无用处 - 这样您同样乐意省略参数 - 那么您可以为 @987654335 提供默认值您知道的 @ 参数可以让您的代码编译。但是,这并不能很好地扩展:您只能在没有以后要指定的参数时省略参数,除非您使用一些hackery来模拟命名参数(如果有兴趣,请谷歌)。如果您对类型感兴趣,调用者必须指定它(如我的回答)。 -
您希望
fcn(1, std::nullopt);调用哪个函数?任何T2都是有效的(只要它对optional有效)
标签: c++ templates optional generic-programming