const references in c++ templates

后端 未结 3 1238
没有蜡笔的小新
没有蜡笔的小新 2021-02-05 09:53

In a C++ template with the generic type T, I can use

const T &

to get a reference to a constant T. However, if now T itself is a reference

相关标签:
3条回答
  • 2021-02-05 09:55

    Remove the reference:

    template<typename T>
    void Test(const typename std::remove_reference<T>::type & param)
    {
            param = 20;
    }
    

    Now it works as expected.

    0 讨论(0)
  • 2021-02-05 10:10

    I have encountered the very same problem. It seems that the '&' type conversion operator binds stronger than the 'const' qualifier. So when we have this code:

    template<class t>
    void fun(const t i)
    {
    }
    
    fun<int&>();
    

    the function ends up with type void(int&), not the expected void(const int&).

    To solve this problem, I have defined this template:

    template<class t> struct constify { typedef t type; };
    template<class t> struct constify<t&> { typedef const t& type; };
    

    Now define your function as:

    template<class t>
    void fun(typename constify<t>::type i)
    {
    }
    
    fun<int&>();
    

    The instantiated function will have the type void(const int&), as needed.

    0 讨论(0)
  • 2021-02-05 10:22

    You can always use template specialisation to implement a different version for any kind of reference:

    template <typename T> struct X {
      void foo(T const&);
    };
    
    template <typename T> struct X<T&> {
      void foo(T const&);
    };
    

    Now, X<int>::foo expects an int const& and X<int&>::foo expects an int const&, too.

    However, it is not entirely clear from your question what you are trying to do exactly.


    Edit: My g++ version (4.6.1) does not complain without template specialisation for the following

    int i = 7;
    X<int&>(i);
    

    While it does for

    X<int&>(7);
    

    Which is correct IMO, because you try to convert a temporary (7) to a mutable reference (even if that is a reference to a const reference).


    Edit 2: If you want to reduce duplicate code, then do not specialise your original class, but use this:

    template <typename T> struct R {
      typedef T& Ref;
      typedef T const& ConstRef;
    };
    
    template <typename T> struct R<T&> {
      typedef T& Ref;
      typedef T const& ConstRef;
    };
    
    template<typename T> struct X {
      void foo(typename R<T>::ConstRef x);
    };
    
    0 讨论(0)
提交回复
热议问题