[英]Deduce class template parameter with default
I'd like to have a class template with parameters with and without defaults.我想要一个带有和不带默认参数的 class 模板。 And I'd like a parameter with a default to be able to be deduced from the constructor.
而且我希望能够从构造函数中推导出一个具有默认值的参数。 An example:
一个例子:
template <typename T, typename Compare = std::less<T> >
struct foo {
foo(const Compare& c = Compare{}) { }
};
foo<int> x; // Works, c = std::less<int>{}
foo<int, std::greater<int>> y; // Works, c = std::greater<int>{}
auto cmp = [](const int&, const int&){ return true; };
foo<int, decltype(cmp)> z(cmp); // Works (with C++20), c = cmp
foo<int> bad(cmp); // Fails
The issue with the bad code seems to be that since only template parameter T
is provided, the default of std::less<int>
is used for Compare
.错误代码的问题似乎在于,由于只提供了模板参数
T
,因此默认std::less<int>
用于Compare
。 This makes the constructor's signature foo(const std::less<int>&)
, which is not compatible with the call of foo(<lambda>)
, as the lambda can't be converted to std:less<int>
.这使得构造函数的签名
foo(const std::less<int>&)
与foo(<lambda>)
的调用不兼容,因为 lambda 无法转换为std:less<int>
。
If another argument is added to the constructor, so that all template parameters can be deduced from constructor arguments, then it works.如果在构造函数中添加另一个参数,以便可以从构造函数 arguments 推导出所有模板参数,则它可以工作。
template <typename T, typename Compare = std::less<T> >
struct bar {
bar(T, const Compare& c = Compare{}) { }
};
bar z2(int{}, [](){return true;});
While it might seem the issue is that the default value for the Compare
parameter is taking precedence over what could be deduced, that's not the case.虽然问题似乎是
Compare
参数的默认值优先于可以推断的值,但事实并非如此。
The real issue is this:真正的问题是这样的:
Class template argument deduction is only performed if no template argument list is present.
Class 模板参数推导仅在不存在模板参数列表时执行。 If a template argument list is specified, deduction does not take place.
如果指定了模板参数列表,则不会进行推导。
Once a single template parameter is specified, no deduction will take place.一旦指定了单个模板参数,就不会进行任何扣除。 Even though it would seem it is still possible to determine what the remaining template parameters would be.
即使看起来仍然可以确定剩余的模板参数是什么。
Without a default value for a template parameter, the compiler with fail earlier with an diagnostic about an incorrect number of template parameters.如果没有模板参数的默认值,编译器会提前失败,并诊断出模板参数数量不正确。 So this limitation can not be observed without also using default values for template parameters.
因此,如果不使用模板参数的默认值,则无法观察到此限制。
In summary, at instantiation, class template parameters must be fully known.总之,在实例化时,必须完全知道 class 模板参数。 This can be done by (in order of priority if more than one applies):
这可以通过以下方式完成(如果有多个应用,则按优先级顺序):
These options are not allowed:不允许使用以下选项:
make_foo
works. make_foo
有效。
template,class T>
struct tag_t{};
template<class T>
constexpr tag_t<T> tag={};
template <typename T, typename Compare = std::less<T> >
struct foo {
foo(tag_t<T>, const Compare& c = Compare{}) { }
foo(const Compare& c = Compare{}) { }
};
also works:也有效:
foo f(tag<int>, cmp);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.