n. *_* m. 20 c++ language-lawyer template-meta-programming
考虑这个程序:
#include <iostream>
#include <type_traits>
using namespace std;
struct russell {
template <typename barber,
typename = typename enable_if<!is_convertible<barber, russell>::value>::type>
russell(barber) {}
};
russell verify1() { return 42L; }
russell verify2() { return 42; }
int main ()
{
verify1();
verify2();
cout << is_convertible<long, russell>::value;
cout << is_convertible<int, russell>::value;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果某些类型barber无法转换为russell.我们试图通过使其可转换(启用转换构造函数)来创建一个悖论.
输出00有三个流行的编译器,虽然构造函数显然在工作.
我怀疑行为应该是未定义的,但在标准中找不到任何内容.
该计划的输出应该是什么,为什么?
在重载解析期间,模板参数推导必须实例化默认参数以获取一组完整的模板参数,以便使用(如果可能)实例化函数模板.因此,实例化is_convertible<int, russell>是必要的,其内部调用重载决策.构造函数模板位于russell默认模板参数的实例化上下文中.
关键是is_convertible<int, russell>::value评估默认模板参数russell,它自己命名 is_convertible<int, russell>::value.
is_convertible<int, russell>::value
|
v
russell:russell(barber)
|
v
is_convertible<int, russell>::value (not in scope)
Run Code Online (Sandbox Code Playgroud)
核心问题287(未采用的)决议似乎是主要编制者事实上的规则.因为实例化的要点恰好在实体之前,value所以当我们评估其初始化时,声明不在范围内; 因此,我们的构造函数有一个替换故障,is_convertible在main收益率false.问题287阐明哪些声明属于范围,哪些声明不属于,即value.
Clang和GCC在处理这种情况方面略有不同.以自定义,透明的特征实现为例:
#include <type_traits>
template <typename T, typename U>
struct is_convertible
{
static void g(U);
template <typename From>
static decltype(g(std::declval<From>()), std::true_type{}) f(int);
template <typename>
static std::false_type f(...);
static const bool value = decltype(f<T>()){};
};
struct russell
{
template <typename barber,
typename = std::enable_if_t<!is_convertible<barber, russell>::value>>
russell(barber) {}
};
russell foo() { return 42; }
int main() {}
Run Code Online (Sandbox Code Playgroud)
Clang默默地翻译了这个.GCC抱怨无限递归链:它似乎认为value在默认参数的递归实例化中确实存在范围,因此继续实例化value一次又一次的初始化器.但是,可以说Clang是正确的,因为[temp.point]/4中当前和起草的相关短语都要求PoI 在最近的封闭声明之前.即,非常声明不被认为是部分实例化的一部分(尚未).如果考虑上述情况,Kinda会有意义.GCC的解决方法:使用声明表单,在声明初始化程序实例化之前,不会声明该名称.
enum {value = decltype(f<T>()){}};
Run Code Online (Sandbox Code Playgroud)
这也与GCC一起编译.
| 归档时间: |
|
| 查看次数: |
508 次 |
| 最近记录: |