C++ 模板构造函数可以';别叫了
我正在实现一个类似于std::list的类。我遇到了调用错误构造函数的问题 下面是一段有效的代码片段:C++ 模板构造函数可以';别叫了,c++,templates,overload-resolution,C++,Templates,Overload Resolution,我正在实现一个类似于std::list的类。我遇到了调用错误构造函数的问题 下面是一段有效的代码片段: #include <iostream> template <typename T> class dslist { public : typedef size_t size_type ; public : explicit dslist( const size_type count , const T &value ) ; temp
#include <iostream>
template <typename T>
class dslist
{
public :
typedef size_t size_type ;
public :
explicit dslist( const size_type count , const T &value ) ;
template <typename InputIt>
explicit dslist( InputIt first , InputIt last ) ;
} ;
template <typename T>
dslist<T>::dslist( const size_type count , const T &value )
{
std::cout << "count, value ctor" << std::endl ;
}
template <typename T>
template <typename InputIt>
dslist<T>::dslist( InputIt first , InputIt last )
{
std::cout << "Iterator" << std::endl ;
}
int main()
{
dslist<int> l( 10 , 20 ) ;
return 0 ;
}
#包括
模板
类dslist
{
公众:
typedef size_t size_type;
公众:
显式dslist(常量大小\类型计数、常量T和值);
模板
显式dslist(先输入,后输入);
} ;
模板
dslist::dslist(常量大小\类型计数、常量T和值)
{
std::cout因为10
和20
的值是int
当然迭代器匹配得最好。所以:
您可以添加显式强制转换(例如size\u t(10)
或static\u cast(10)
)来调用正确的强制转换
为size\t
创建一个用户定义的文本,因为没有此文本的内置文本
给定dslist l(10,20);
,模板构造函数在重载解析中获胜,因为它是精确匹配的。而第一个构造函数需要从int
(类型10
)隐式转换为size\t
(无符号整数类型)
您可以使用从重载集中排除不需要的专门化。例如,迭代器类型应该支持运算符*
template <typename InputIt, typename = decltype(*std::declval<InputIt>())>
explicit dslist( InputIt first , InputIt last ) ;
模板
显式dslist(先输入,后输入);
如果您查看std::list构造函数,它具有相同的构造函数。如果我使用std::list而不是我的类(dslist),则会调用正确的构造函数。我试图弄清楚std::list在内部是如何工作的,以及如何为std::list调用第一个构造函数。@DevenTopiwala如果我们查看,我们会看到这一点“如果InputIt满足LegacyInputIterator,则此重载仅参与重载解析,以避免与重载(2)不明确”。这可能是通过使用类似或等效于宋元耀所示的方法实现的。@DevenTopiwalastd::list
实现(在stdlibc++中)使用SFINAE(如另一个答案中所建议的)“DevenTopiwala公平点,我没有考虑<代码> STD::清单但是只看了你的代码。其他人正确地指出,<代码> STD::清单< /C> >用Sfaye来避免这个问题。这是完全足够的,因为至少有一个到其他超载的参数永远不会。@宋元耀,如果我这样做,STD::向量V(10)。;dslist l1(std::begin(v),std::end(v));(在main中)。这会导致一个错误。上述解决方案部分解决了该问题。@DevenTopiwala My fault。已修复。
template <typename InputIt, typename = decltype(*std::declval<InputIt>())>
explicit dslist( InputIt first , InputIt last ) ;