首页 > 解决方案 > 无法调用模板构造函数

问题描述

我正在实现一个类似于 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 ;
}

如果我运行它,将调用迭代器构造函数。但是,实际上应该调用第一个构造函数 (count, value)。

在这种情况下如何确保调用第一个构造函数?

编辑以添加从答案中提取的解决方案:

解决方案

#include <iostream>
#include <utility>
#include <vector>
#include <type_traits>

template <typename T>
class dslist
{
public :
    typedef size_t    size_type ;
public :
    explicit dslist( const size_type count , const T &value ) ;
    template <typename InputIt, typename = decltype(*std::declval<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, typename>
dslist<T>::dslist( InputIt first , InputIt last )
{
    std::cout << "Iterator" << std::endl ;
}

int main()
{
    dslist<int> l( 10 , 20 ) ;

    std::vector<int> v( 10 ) ; 
    dslist<int> l1( std::begin( v ) , std::end( v ));
    return 0 ;
}

标签: c++templatesoverload-resolution

解决方案


给定dslist<int> l( 10 , 20 ) ;,模板构造函数在重载决议中获胜,因为它是完全匹配的。而第一个构造函数需要从int(的类型10)到size_t(无符号整数类型)的隐式转换。

您可以使用SFINAE从重载集中排除不需要的特化。例如,迭代器类型应该支持operator*.

template <typename InputIt, typename = decltype(*std::declval<InputIt>())>
explicit dslist( InputIt first , InputIt last ) ;

居住


推荐阅读