2013-09-16 81 views
1

我不明白这是为什么不工作:依赖模板的参数类型

template <typename T> 
struct TypeWrapper 
{ 
    typedef T type; 
}; 
template <> 
struct TypeWrapper<char*> 
{ 
    typedef std::string type; 
}; 
template <> 
struct TypeWrapper<const char*> 
{ 
    typedef std::string type; 
}; 
template <int N> 
struct TypeWrapper<char[N]> 
{ 
    typedef std::string type; 
}; 
template <int N> 
struct TypeWrapper<const char[N]> 
{ 
    typedef std::string type; 
}; 

class A 
{ 
public: 
    template< typename T > 
    A(const typename TypeWrapper<T>::type& t) 
    { 
     // do smthing 
     std::cout << t << std::endl; 
    } 
}; 

int main(void) 
{ 
    A a(42); 

    return 0; 
} 

我与Visual Studio 2010的编译,我得到以下错误:

error C2664: 'A::A(const A &)' : cannot convert parameter 1 from 'int' to 'const A &' 

如果我改变构造A到这一个它的工作原理:

A(const T& t) 

但我想处理char *类型作为std ::字符串和可能其他类型adju stements,whithouth复制构造函数(定义特定构造每种类型,这个工程)

+2

你不能推断出这样的模板参数。这与尝试推断何时使用'std :: vector '相同。 – chris

回答

2

我认为下列哪项不是语法正确

A(typename const TypeWrapper<T>::type& t) 

应该

A(const typename TypeWrapper<T>::type& t) 

A(typename TypeWrapper<T>::type const& t) 

无论如何,即使您修复临时表,您的示例也不会编译问题。 VC++试图调用(编译器生成的)复制构造函数而不是你定义的构造函数,因为模板参数推导总是会在你的构造函数上失败。原因是标准定义引用了一个嵌套类型名称,比如你的构造函数参数(typename TypeWrapper<T>::type)是一个非推导的上下文。

这使您无法构建A,因为必须推导出构造函数的模板参数;你不能明确地指定它们。


您应该诉诸超载。

class A 
{ 
public: 
    template< typename T > 
    A(T const& t) 
    { 
     // do smthing 
     std::cout << t << std::endl; 
    } 

    A(std::string const& s) 
    { 
     std::cout << "string" << std::endl; 
    } 

    A (char const *s) 
    { 
     std::cout << "char *" << std::endl; 
    } 

    template<std::size_t N> 
    A (const char (&arr)[N]) 
    { 
     std::cout << "char array" << std::endl; 
    } 
}; 
+0

我尝试了所有3个排列,没有一个确实工作;实际上,我自然地键入了常量类型名称......其中一个,你在问题中看到的是我的实验结果:)至于你答案的最后部分,我不确定我得到它...... – foke

+0

@foke我不确定你在说什么3种排列方式。哪一部分不清楚? – Praetorian

+0

我想避免重载,因为在现实世界的情况下构造函数是少一点点的 – foke