为什么只有一个元素的支撑init列表的类型会切换到元素本身的类型
Why does type of braced-init-list with one element get switched to the type of the element itself?
在下面的代码中,使用参数{1,2}对实例b的成员函数F的调用编译并调用B::F(std::initializer_list<int>)
。但是,如果我从支持的init列表中删除一个元素并只使用{1},我会得到一个错误
9 : error: no matching function for call to 'begin(int)'
using type = decltype(std::begin(std::declval<T>()));
我不明白为什么编译器要找begin(int)
,而不是begin(initializer_list<int>)
我一直在玩这个https://godbolt.org/g/tMyYQs,我在clang和g++上都得到了同样的错误。我错过了什么?
#include <type_traits>
#include <iterator>
template< bool B, class T = void >
using enable_if_t = typename std::enable_if<B,T>::type;
template <typename T>
struct mytrait {
using type = decltype(std::begin(std::declval<T>()));
};
template <typename T>
class A {
public:
template <typename TA, typename =
enable_if_t<std::is_same<T, typename mytrait<TA>::type>::value>>
A(TA &&){}
};
class B
{
public:
void F(A<int>);
void F(std::initializer_list<int>);
};
int main()
{
B b;
b.F({1,2}); // compiles fine
#if 0
b.F({1}); // causes mytrait<int>::type to be examined,
// not mytrait<std::initializer_list<int>>::type
#endif
}
好吧,我想我想通了。当编译器看到b.F({1})
时,它试图找出要调用F的哪个重载。它发现有一个重载需要A<int>
,因此,通过复制列表初始化,它试图查看是否可以使用A<int>{1}
构造A<int>
。文本1
的类型是int。因此TA被推导为int。mytrait<int>
试图确定decltype(std::begin(declval<int>()))
,类型int没有std::begin,因此编译器出错。
对于b.F({1,2})
,A<int>
没有接受两个输入的构造函数,因此甚至没有尝试列表初始化。
看起来我可以通过将mytraits模板声明更改为来解决这个问题
template <typename T, typename = decltype(std::begin(std::declval<T>()))>
struct mytraits {...};
这似乎是在利用SFINAE制作mytrait<int>::type是替换失败。
相关文章:
- C++ 未初始化的本地(非全局)int 数组中的元素类型到底是什么?
- 如何将 n 个连续元素插入到元素类型不可复制的 std::vector 中?
- 元函数使用 decltype 返回元素类型
- STDLIB中容器元素类型有什么要求?
- 使用 dectlype 推断模板元素类型中的数据类型是否正确?
- boost multi_index - 如果元素类型仅支持移动语义,如何遍历它?
- 打印/修改类对象的特定成员变量,其类定义列表 (STL) 包含的元素类型
- 使用声明中的元素类型隐式初始化 std::array
- 使用 SFINAE 和 void_t 来确定容器内的元素类型
- 键入 trait 以获取 std::array 或 C 样式数组的元素类型
- 如何在QTScript中将QLIST内部的QMAP注册为元素类型
- 关联容器,比较函数不是元素类型的一部分吗?
- 特征稀疏矩阵的 CoeffRef 中的错误,元素类型为向量
- 在编译时间检查模板参数类型是否设置或多键,并且容器的元素类型是算术的
- 从函数模板参数中自动推论对容器的元素类型
- 直接获取基于范围的循环中的元素类型 **例如"using"
- 定义指向 C++ 中相同元素类型的元素
- 如何在C++中一一阅读 CIN?元素类型不同
- 如何从STL容器实例中获取元素类型
- 容器的const_cast元素类型