2012-02-29 83 views
3

我有一个模板类,可以(有时必须)采用const类型,但是有一种方法会返回具有相同类型的类的新实例,但应该明确非const。例如,下面的代码编译失败在模板中获取非const类型

template<class T> class SomeClass { 
public: 
    T val; 
    SomeClass(T val) : val(val) {} 
    SomeClass<T> other() { 
     return SomeClass<T>(val); 
    } 
}; 

int main() { 
    SomeClass<const int> x(5); 
    SomeClass<int> y = x.other(); 
    return 0; 
} 

,因为即使有构造期间VAL副本,它复制到同一类型 - const int。就像你可以在模板中区分Tconst T一样,有没有办法区分T和“nonconst T”?

+0

我从来没有听说过你可以在模板参数中使用'const'修饰符。 – 2012-02-29 18:41:36

回答

4
SomeClass<typename std::remove_const<T>::type> other() 
{ 
    return SomeClass<typename std::remove_const<T>::type>(val); 
} 

std::remove_const<type_traits>,是C++ 11。 Boost.TypeTraits中可能有boost::remove_const,或者你甚至可以推出自己的。也可以使用std::remove_cv

+0

如果你不需要C++ 11,那么在一个充分新的编译器中可能会有'std :: tr1 :: remove_const'。 – kennytm 2012-02-29 18:55:13

+0

是的,TypeTraits中有一个'boost :: remove_const'。 – 2012-02-29 18:56:35

+0

'',虽然出现在我的系统(boost,tr1和C++ 11变体)上,用'clang ++'和'g ++'编译时表示找不到。无论如何,源代码的高峰给了我std :: remove_const的定义,它的工作!谢谢! – 2012-02-29 19:07:13

0

本质上的问题是,有两种不能严格转换的不同类型。

您可以使用/从type_traits返回std::remove_const

#include <type_traits> 

template<class T> 
class SomeClass { 
public: 
    T val; 
    SomeClass(T p) : val(p) { 
    } 

    SomeClass<typename std::remove_const<T>::type> other() { 
     return static_cast<SomeClass<typename std::remove_const<T>::type> >(val); 
    } 
}; 

int main() { 
    SomeClass<const int>x(5); 
    SomeClass<int>y = x.other(); 
    return 0; 
} 
4

,如果你使用的是C++ 11。否则,您既可以使用std::remove_const,您可以使用此:

struct <typename T> 
struct remove_const 
{ 
    typedef T type; 
}; 
struct <typename T> 
struct remove_const<const T> 
{ 
    typedef T type; 
}; 

哪个不相同。

+1

+1 - 耐人寻味! – 2012-02-29 19:21:13