问题描述
我刚刚发现了以下技术.它看起来非常接近建议的概念语法之一,可以在Clang,GCC和MSVC上完美运行.
I have just discovered the following technique. It looks very close to one of proposed concepts syntax, works perfectly on Clang, GCC and MSVC.
template <typename T, typename = typename std::enable_if<std::is_rvalue_reference<T&&>::value>::type>
using require_rvalue = T&&;
template <typename T>
void foo(require_rvalue<T> val);
我试图通过搜索请求(例如"sfinae in type alias")找到它,但一无所获.这种技术有名称吗,语言实际上允许吗?
I tried to find it with search requests like "sfinae in type alias" and got nothing. Is there a name for this technique and does the language actually allows it?
完整示例:
#include <type_traits>
template <typename T, typename = typename std::enable_if<std::is_rvalue_reference<T&&>::value>::type>
using require_rvalue = T&&;
template <typename T>
void foo(require_rvalue<T>)
{
}
int main()
{
int i = 0;
const int ic = 0;
foo(i); // fail to compile, as desired
foo(ic); // fail to compile, as desired
foo(std::move(i)); // ok
foo(123); // ok
}
推荐答案
关于名字什么也不能说,但是在我看来这是肯定的.
Can't say anything about the name, but this seems to me to be a yes.
相关措辞为 [temp.alias]/2 :
和sfinae规则 [temp.deduct]/8 :
采用类型为require_rvalue<T>
的参数的行为的确就像我们替换了该别名一样,别名为我们提供了T&&
或替换失败-并且该替换失败可以说是在直接上下文中 of the substitution and so is "sfinae-friendly" as opposed to being a hard error. Note that even though the defaulted type argument is unused, as a result of CWG 1558 (the void_t
rule), we got the addition of [temp.alias]/3:
这可以确保我们仍然替换为默认的type参数以触发所需的替换失败.
This ensures that we still substitute into the defaulted type argument to trigger the required substitution failure.
问题的第二个未说部分是它是否实际上可以充当转发参考. [temp.deduct.call]/3中有此规则:
The second unsaid part of the question is whether this actually can behave as a forwarding reference. The rule there is in [temp.deduct.call]/3:
是否具有一个模板参数的别名模板(其关联类型是对其cv不合格模板参数的右值引用)被视为转发参考?好吧,[temp.alias]/2表示require_rvalue<T>
等同于T&&
,而T&&
是正确的事情.可以这么说...是的.
Is an alias template with one template parameter whose associated type is an rvalue reference to its cv-unqualified template parameter considered a forwarding reference? Well, [temp.alias]/2 says that require_rvalue<T>
is equivalent to T&&
, and T&&
is the right thing. So arguably... yeah.
所有编译器都将其视为此类,这无疑是一个不错的验证.
And all the compilers treat it as such, which is certainly a nice validation to have.
不过,请注意 CWG 1844 ,缺乏针对即时上下文的实际定义,该示例还依赖于默认参数的替换失败-问题指出该实现存在差异.
Although, note the existence of CWG 1844 and the lack of actual definition for immediate context, and the example there which also relies upon a substitution failure from a defaulted argument - which the issue states has implementation divergence.
这篇关于为sfinae使用别名模板:语言允许吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!