C++ 模板构造函数可以';别叫了

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

我正在实现一个类似于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 ) ;
    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)不明确”。这可能是通过使用类似或等效于宋元耀所示的方法实现的。@DevenTopiwala
    std::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 ) ;