本文介绍了为sfinae使用别名模板:语言允许吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚发现了以下技术.它看起来非常接近建议的概念语法之一,可以在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使用别名模板:语言允许吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 16:13