2

我对下面的句子感到困惑,我理解他们用于转换成员函数的示例但不理解构造函数成员函数模板场合,Mankarse 给出的有用示例

因为显式模板实参列表跟在函数模板名之后,并且因为转换成员函数模板和构造函数成员函数模板在调用时不使用函数名,所以无法为这些函数模板提供显式模板实参列表。 --14.5.2.5 N3242

struct A {
    template <class T> operator T*();
};
template <class T> A::operator T*(){ return 0; }
template <> A::operator char*(){ return 0; } // specialization
template A::operator void*(); // explicit instantiation

int main() 
{
   A a;
   int *ip;
   ip = a.operator int*(); // explicit call to template operator
   // A::operator int*()
}

类模板的成员函数的模板参数由调用该成员函数的对象类型的模板参数确定。--14.5.1.1.2 N3242

所以我需要自己扣除模板参数或使用包装器。
libstdc++在读取标准库时给出的例子:

template<typename _Container>
class back_insert_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
   protected:
      _Container* container;
   public:
       explicit
       back_insert_iterator(_Container& __x) : container(&__x) { }
}
/*
 *it use a wrapper :
 */
template<typename _Container>
inline back_insert_iterator<_Container>
back_inserter(_Container& __x)
{ return back_insert_iterator<_Container>(__x); }
4

2 回答 2

5

您永远不能为构造函数模板提供显式模板参数列表。构造函数模板必须总是推导出它们的参数:

struct A {
    template<typename U> A() {}
};
template <typename T>
struct B {
    B() {}
};
struct C {
    template<typename U> C(U t) {}
};
template <typename T>
struct D {
    template<typename U> D(U t) {}
};

int main()
{
    //auto a1 = A<int>{}; //illegal -- A is not a template
    //A can never be instantiated...

    auto b = B<int>{}; //default-constructs a B<int>

    //auto c = C<double>{1.}; //illegal - C not a template

    //Constructs a C, deduces `U = double` constructor:
    auto c = C{1.};
    //Constructs a D<int>, deduces `U = double` constructor:
    auto d = D<int>{1.};
}
于 2013-06-04T15:57:55.840 回答
1

您可以使用中间模板类对 ctor 进行显式参数 - 它会推断出您想要的类型

#include <iostream>
using namespace std;

template <typename T> struct tag { using type = T;};

class My {
public:
    template <typename T> My(tag<T>) {
        cout << "ctor of " << typeid(T).name();
    }
};

int main(int argc, const char * argv[]) {

    auto a = My(tag<int>());
}
于 2016-04-28T16:55:37.313 回答