简体   繁体   English

如何使用顶级const解决此问题?

[英]How to resolve this issue with top-level const?

I have a class template that contains two similar member functions: 我有一个包含两个类似成员函数的类模板:

template<class T>
class MyTemplate {
   // other stuff, then
   static T* member( T& ); //line 100
   static const T* member( const T& ); //line 101

}; };

which I instantiate like this: 我实例化如下:

MyTemplate<int* const>

and Visual C++ 9 complains: 和Visual C ++ 9抱怨:

mytemplate.h(101) : error C2535: 'int* MyTemplate<T>::member(T &)' :
   member function already defined or declared
with
[
    T=int *const 
]
mytemplate.h(100) : see declaration of 'MyTemplate::member'
with
[
    T=int *const 
]
somefile.cpp(line) : see reference to class template instantiation
    'MyTemplate<T>' being compiled
with
[
    T=int *const 
]

I certainly need the two versions of member() - one for const reference and one for non-const reference. 我当然需要两个版本的member() - 一个用于const引用,一个用于非const引用。 I guess the problem has something with top-level const qualifiers, but can't deduce how to solve it. 我猜这个问题与顶级const限定符有关,但不能推断出如何解决它。

How do I resolve this problem so that I still have two versions of member() and the template compiles? 我如何解决此问题,以便仍然有两个版本的member()和模板编译?

When T is int * const , T is already const , so T& and const T& are both int * const . Tint * constT已经是const ,所以T&const T&都是int * const

Or do you mean in this case, you need your class to look like: 或者你的意思是在这种情况下,你需要你的班级看起来像:

class MyTemplate_int_p_const{
     static int * member (int *&);
     static int * const member (int * const &);
};

You can add this to your main template to achieve this: 您可以将其添加到主模板中以实现此目的:

template<class T>
class MyTemplate<const T>
{
    static T * member(T&);
    static const T* member(const T&);
};

As a responds to the OP's comment, if you don't want to use partial specialization, you'll need type_traits. 作为对OP评论的回应,如果你不想使用部分特化,你需要type_traits。 It is supported by C++0x, and for VC++9, you can use boost . 它受C ++ 0x支持,对于VC ++ 9,您可以使用boost

In the following code, the non_const version of member will take a dummy_type ( a pointer to member function) if T is already const. 在下面的代码中,如果T已经是const,则non_const版本的member将采用dummy_type (指向成员函数的指针)。 So the non_const overload would not exist. 所以non_const重载不存在。

#include <type_traits>
template<class T>
class MyTemplate {
   // other stuff, then

   //void dummy(void);
   typedef void (*dummy_type)(void);
   typedef typename std::conditional<std::is_const<T>::value, dummy_type, T>::type T_no_const;
   typedef typename std::remove_const<T>::type T_remove_const;
   static T_no_const* member( T_no_const& t ) //line 100
   {
       if (std::is_same<T, T_no_const>::value)
       {
           return member_portal(t);
       }
       else
           return NULL;
   }
   static T_no_const* member_portal(dummy_type&){return NULL;};
   static T_remove_const* member_portal(T_remove_const&);
   static const T* member( const T& ); //line 101

};


int main()
{
    MyTemplate<int * const> mt;
    MyTemplate<int *> mtt;
    return 0;
}

This is the first time that I play with type_traits . 这是我第一次玩type_traits It can pass compilation under g++ 4.5.2 with C++0x enabled. 它可以在g ++ 4.5.2下通过编译,启用C ++ 0x。 But I've never run it. 但我从来没有跑过它。

Main idea is, when T is const, the non_const version of member takes a argument of an arbitrary type ( a type that is not likely to be used any where else, and to not likely to be implicitly converted to), thus the non_const version disappears. 主要思想是,当T为const时,non_const版本的成员采用任意类型的参数(一种不太可能在任何其他地方使用的类型,并且不太可能被隐式转换为),因此non_const版本消失。 But in the way, the logic breaks in the implementation of member ( as the argument type is to be used, but is not expected). 但顺便说一句,逻辑在member的实现中断(因为要使用参数类型,但不是预期的)。 So the main logic of member is move another function of member_portal . 所以member的主要逻辑是移动member_portal另一个函数。

The explanation given by fefe is correct. fefe给出的解释是正确的。 Foo const& and Foo const const& will simply evaluate to the same type, hence your function overloading does not work. Foo const&Foo const const&将简单地评估为相同类型,因此您的函数重载不起作用。 In case your template argument is const, I'd suggest specialisation. 如果你的模板参数是const,我建议专业化。

Version A: 版本A:

template<class T>
class MyTemplate {
   static T* member( T& );
   static const T* member( const T& );
};
template<class T>
class MyTemplate<T const> {
   static const T* member( const T& );
};

Version B: 版本B:

template<class T>
class MyTemplate_mutableImpl {
   static T* member( T& );
};
template<class T>
class MyTemplate_constImpl {
   static const T* member( const T& );
};
template<class T>
class MyTemplate : public MyTemplate_mutableImpl<T>, public MyTemplate_constImpl<T> {
};
template<class T>
class MyTemplate<T const> : public MyTemplate_constImpl<T const> {
};

A simple solution would be to disable the function if T is const : 一个简单的解决方案是在Tconst禁用该函数:

#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_const.hpp>

template<class T>
class MyTemplate {
   static T* member( T& );
   struct Disabled {};
   static const T* member(typename boost::mpl::if_<boost::is_const<T>, Disabled, const T&>::type);
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM