在VC2012中我是一个奇怪的人我似乎无法弄清楚通过const引用将const指针传递给模板化参数的函数的语法,模板参数是非常量指针,即:
- template<typename T>
- struct Foo
- {
- void Add( const T& Bar ) { printf(Bar); }
- };
- void main()
- {
- Foo<char*> foo;
- const char* name = "FooBar";
- foo.Add(name); // Causes error
- }
所以我在这里简化了我的问题,但基本上我希望参数’Add’有一个const T即const char *.我试过了:
- void Add( const (const T)& Bar );
- typedef const T ConstT;
- void Add( const (ConstT)& Bar );
- void Add( const typename std::add_const<T>::type& Bar );
这些都不起作用.我得到的确切错误是:
- error C2664: 'Foo<T>::Add' : cannot convert parameter 1 from 'const char *' to 'char *const &'
- with
- [
- T=char *
- ]
- Conversion loses qualifiers
我可以看到它是正确的,但如何解决它没有常量’name’为非const.
解决方法
看起来你的问题是,只要你有一个映射到模板类型的指针类型,你就不能再将指针添加到指向类型,只能指向指针本身.你想要做的是自动添加constness到函数的参数(所以如果T是char *,函数应该接受const char * const&而不是char * const&和你写的那样).唯一的方法是使用另一个模板将constness添加到指针类型的指针,如下所示.我冒昧地包括丢失的标题和更正主要的签名:
- #include <cstdio>
- template<typename T>
- struct add_const_to_pointee
- {
- typedef T type;
- };
- template <typename T>
- struct add_const_to_pointee<T*>
- {
- typedef const T* type;
- };
- template<typename T>
- struct Foo
- {
- void Add( typename add_const_to_pointee<T>::type const & Bar ) { printf(Bar); }
- };
- int main()
- {
- Foo<char*> foo;
- const char* name = "FooBar";
- foo.Add(name); // Causes error
- }
然而,正如另一个人所提到的,如果你使用std :: string而不是C风格的字符串,这个问题就会消失.