[英]template function argument explicit type declaration
I have a list of operator overloads, and I found that they are not acting in the way that I want them to.我有一个运算符重载的列表,我发现它们没有按照我希望的方式运行。 I reduced the problematic code to a couple lines to simulate the problem.
我将有问题的代码减少到几行来模拟问题。 I have a couple template type aliases to help compile time decision making, a template function (an operator in the working code, but here just a generic function), and a class called
var
that takes in two template parameters, an unsigned int
and a bool
( true
= known var, false
= unknown var, just mentioning this so that the naming convention in the following code snippet makes sense).我有几个模板类型别名来帮助编译时决策、一个模板函数(工作代码中的一个运算符,但这里只是一个泛型函数)和一个名为
var
的类,它接受两个模板参数,一个unsigned int
和一个bool
( true
= known var, false
= unknown var, 只是提到这一点,以便以下代码片段中的命名约定有意义)。 Here is the code.这是代码。
template<typename T>
using is_known = typename std::is_same<T, const var<T::ID, true> >::type;
template<typename T>
using is_unknown = typename std::conditional<is_known<T>::value, std::false_type, std::true_type>::type;
template<typename T>
using UK_if_UK = typename std::enable_if<is_unknown<T>::value, T>::type;
template<typename unknown_check_LHS, typename unknown_check_RHS>
constexpr const two_param_type<UK_if_UK<unknown_check_LHS>, UK_if_UK<unknown_check_RHS> > func(const unknown_check_LHS& lhs, const unknown_check_RHS& rhs)
{
return two_param_type<unknown_check_LHS, unknown_check_RHS>
(//generic construction goes here, unimportant...);
}
int main()
{
constexpr const var<0u,true> firstvar(123);
constexpr const var<1u,true> secondvar(456);
func(firstvar,secondvar);
func<std::decltype(firstvar),std::decltype(secondvar)>(firstvar,secondvar);
}
The two calls to func()
seem identical to me, and they should both fail (in the working code there are other options once this function SFINAEs out).对
func()
的两次调用对我来说似乎相同,它们都应该失败(在工作代码中,一旦此函数 SFINAE 退出,还有其他选项)。 However, only the second call, where I explicitly declare the types, does the compiler throw an error.但是,只有在我明确声明类型的第二个调用中,编译器才会抛出错误。 It compiles the first call to
func()
perfectly, and even worse, it operates and returns with type "known" ( var<(some unsigned),true>
), even though the type alias in the return type should SFINAE the function out of overload resolution.它完美地编译了对
func()
的第一次调用,更糟糕的是,它以“已知”类型( var<(some unsigned),true>
)进行操作和返回,即使返回类型中的类型别名应该 SFINAE 函数重载决议。 I am using operators, so explicitly declaring the type is not an option for me.我正在使用运算符,因此明确声明类型不是我的选择。 More importantly, however, I want to know why the function is not SFINAEing out.
然而,更重要的是,我想知道为什么该函数没有 SFINAE 出来。 Any help would be appreciated.
任何帮助,将不胜感激。 Thank you.
谢谢你。
Note: The specific error is:注:具体错误为:
error: no matching function for call to 'func(const var<0u, true>&, const var<1u, true>&)'
Also, I have tested is_known
, is_unknown
, and UK_if_UK
to work properly, so no need to test those.另外,我已经测试了
is_known
、 is_unknown
和UK_if_UK
可以正常工作,所以不需要测试它们。 Thank you.谢谢你。
The two calls to func seem identical to me
对 func 的两次调用对我来说似乎相同
Wrong.错误的。
They are different.它们是不同的。
It's a constness problem.这是一个常数问题。
With和
constexpr const var<0u,true> firstvar(123);
constexpr const var<1u,true> secondvar(456);
and the signature of func()
as follows和
func()
的签名如下
template<typename unknown_check_LHS, typename unknown_check_RHS>
constexpr /* ... */ func (const unknown_check_LHS & lhs,
const unknown_check_RHS & rhs)
calling打电话
func(firstvar,secondvar);
the types, unknown_check_LHS
and unknown_check_RHS
, are detected as var<0u, true>
and var<1u, true>
respectively.类型
unknown_check_LHS
和unknown_check_RHS
分别被检测为var<0u, true>
和var<1u, true>
。
Please observe: var<0u, true>
and var<1u, true>
, not const var<0u, true>
and const var<1u, true>
.请注意:
var<0u, true>
和var<1u, true>
,而不是const var<0u, true>
和const var<1u, true>
。
On the contrary, explicating the types as follows相反,解释类型如下
func<decltype(firstvar), decltype(secondvar)>(firstvar,secondvar);
(and please: decltype()
, not std::decltype()
), unknown_check_LHS
and unknown_check_RHS
are explicated as const var<0u, true>
and const var<1u, true>
respectively. (并且请:
decltype()
,而不是std::decltype()
), unknown_check_LHS
和unknown_check_RHS
分别解释为const var<0u, true>
和const var<1u, true>
。
Observe that now the types are constant .请注意,现在类型是constant 。
Observe how is defined is_know
观察
is_know
是如何定义的
template<typename T>
using is_known = typename std::is_same<T, const var<T::ID, true> >::type;
It compare the type T
with a constant type.它将类型
T
与常量类型进行比较。
So, in the first case (with template types not-constant), is_known
is false;所以,在第一种情况下(模板类型不是常量),
is_known
是假的; in the second case (with constant template types), it's true.在第二种情况下(使用常量模板类型),这是真的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.