函数模板的非依赖默认模板参数是否允许SFINAE? [英] Do non-dependent default template arguments of function templates allow for SFINAE?

查看:133
本文介绍了函数模板的非依赖默认模板参数是否允许SFINAE?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里的非依赖是指不依赖于该特定函数模板的任何其他模板参数。

With "non-dependent" here I mean "non-dependent on any other template arguments of that specific function template".

在回答这个问题,我想我找到了答案,但根据@Johannes(在我的回答的评论),我误解标准这里。以下面的简单例子:

While answering this question, I thought I found the answer, but according to @Johannes (in the comments to my answer), I'm misinterpreting the standard here. Take the following simple example:

#include <type_traits>

template<class T>
struct X{
  template<class U = typename T::type>
  static void foo(int){}
  static void foo(...){}
};

int main(){
  X<std::enable_if<false>>::foo(0);
}

Live version。

是否有任何保证以上编译? GCC和Clang不同意此处,当在他们之间切换时在现场版本中看到。有趣的是,虽然,GCC接受以下内容:

Is there any guarantee that the above compiles? GCC and Clang disagree here, as can be seen in the live version when switching between them. Interestingly, though, the following is accepted by GCC:

#include <type_traits>

template<class T>
struct X{
  template<bool = T::f()>
  static void foo(int){}
  static void foo(...){}
};

struct Y{
  static bool f(){ return true; }
};

int main(){
  X<Y>::foo(0);
}

Live version。

第二个片段只会打印 foo(int) if T 包含 constexpr 静态函数 f 。再次,有趣的是,如果你从 Y 中完全删除 f (或者传递, int ),GCC抱怨缺少的成员,表明它不允许SFINAE - 这与前面的观察相矛盾。 Clang采用所有的变体并应用SFINAE,我想知道是否这是标准保证的。

The second snippet will only print foo(int) if T contains a constexpr static function f. Again, interestingly, if you completely remove f from Y (or pass, say, int instead), GCC complains about a missing member, indicating that it doesn't allow for SFINAE - which is contradictory with the previous observation. Clang takes all variations and applies SFINAE, and I wonder if that's what is guaranteed by the standard.

(FWIW,MSVC与Nov CTP一般同意Clang,如果函数存在,可能是因为它们没有 constexpr ,我提交了一个错误报告这里。)

(FWIW, MSVC with the Nov CTP generally agrees with Clang, but crashes on the second snippet if the function is present, likely because they don't have constexpr. I submitted a bug report here.)

推荐答案

是不正确的,因为当类模板被实例化时,所有成员声明被实例化,除了成员函数和成员函数模板的定义部分和默认参数。该标准还定义了何时精确地实例化函数默认参数。

I think the code in question is incorrect, as when the class template is instantiated, all member declarations are instantiated, except the definition parts and default arguments of the member functions and member function templates. The Standard also defines when the function default arguments are instantiated precisely.

因此,默认模板参数会立即实例化。在这一点上,默认参数可能包括默认模板参数的可能性在我看来是非常小的,因为没有描述这种参数何时会

So default template-arguments are immediately instantiated. The possibility that default arguments could be intended to include default template arguments at this point is very small here in my opinion, because there is no description of when such an argument would be instantiated later.

这符合以下要求:不应在模板参数列表中指定默认模板参数一个类模板的成员,出现在成员类的外部。,因为没有办法在实例化周围的类模板时立即实例化这样的模板参数。

This is in line with the requirement that "A default template-argument shall not be specified in the template-parameter-lists of the definition of a member of a class template that appears outside of the member's class.", since there would be no way that such a template argument be instantiated immediately when instantiating the surrounding class template.

这篇关于函数模板的非依赖默认模板参数是否允许SFINAE?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆