考虑下面的代码示例
#include <iostream>
#include <experimental/optional>
std::experimental::optional<int> dflt(42);
template<const std::experimental::optional<int>& Dflt>
void foo() {
if (Dflt) {
std::cout << "default is set" << std::endl;
} else {
std::cout << "default is not set" << std::endl;
}
}
int main() {
foo<dflt>(); // <-- OK
foo<std::experimental::nullopt>(); // <-- NOT OK
}
我试图实现的是nullopt
作为非类型函数模板参数传递,但它没有编译。它可以与dflt
带有静态存储的全局变量一起使用。
编译器错误消息如下所示:
foo.cc: In function ‘int main()’:
foo.cc:13:34: error: no matching function for call to ‘foo()’
foo<std::experimental::nullopt>();
^
foo.cc:7:6: note: candidate: template<const std::experimental::fundamentals_v1::optional<int>& Dflt> void foo()
void foo() {
^
foo.cc:7:6: note: template argument deduction/substitution failed:
foo.cc:13:34: error: could not convert template argument ‘std::experimental::fundamentals_v1::nullopt’ to ‘const std::experimental::fundamentals_v1::optional<int>&’
foo<std::experimental::nullopt>();
我知道这个例子很愚蠢,但是我的主要问题是,可以nullopt
作为非类型模板参数来传递吗?
更长的答案与模板参数上的约束有关。您的模板参数是引用类型。它的相应参数必须满足[temp.arg.nontype] / 2(强调我的要求)中的要求:
非类型模板参数的模板参数应为模板参数类型的转换常量表达式。对于引用或指针类型的非类型模板参数,常量表达式的值不得引用(或对于指针类型,不得为以下地址):
- 一个子对象
- 临时物体,
- 字符串文字,
- Typeid表达式的结果,或者
- 预定义的 func__变量。
nullopt
是类型的常量nullopt_t
。这显然不是一个optional<int>
。因此,要绑定该const引用,我们将需要实现一个临时实例。但这显然使程序格式错误,如黑体字所示。
不过请注意,您可以让参数成为对的引用nullopt_t
。然后,您可以传递nullopt
参数。我会说,尽管这样的模板的用途是有限的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句