c ++模板中的const引用

emk*_*y08 17 c++ templates const reference

在具有泛型类型T的C++模板中,我可以使用

const T &
Run Code Online (Sandbox Code Playgroud)

获取对常量T的引用.但是,如果现在T本身是引用类型(例如T = int&),则上述术语解析为

int &
Run Code Online (Sandbox Code Playgroud)

而不是

const int &
Run Code Online (Sandbox Code Playgroud)

这很有意义,因为任何引用本身都是不变的.但是,还有一种方法需要一个

const T &
Run Code Online (Sandbox Code Playgroud)

如果T本身是参考类型?

编辑:要评估的示例代码(g ++编译器):

template <typename T> class TemplateClass
{
public:
    void foo(const T &bar) { }
};

int main()
{
    TemplateClass<int &> x;
    x.foo(0);   // <-- compile error: no conversion from int to int&
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Pub*_*bby 22

删除参考:

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

现在它按预期工作.

  • 这既棒极了又搞砸了. (15认同)

bit*_*ask 10

您始终可以使用模板专门化为任何类型的引用实现不同的版本:

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

template <typename T> struct X<T&> {
  void foo(T const&);
};
Run Code Online (Sandbox Code Playgroud)

现在,X<int>::foo期待一个int const&X<int&>::foo期待一个int const&.

但是,从你的问题中你并不完全清楚你要做什么.


编辑:如果没有模板专业化,我的g ++版本(4.6.1)不会抱怨以下内容

int i = 7;
X<int&>(i);
Run Code Online (Sandbox Code Playgroud)

虽然它确实适用

X<int&>(7);
Run Code Online (Sandbox Code Playgroud)

哪个是正确的IMO,因为您尝试将temporary(7)转换为可变引用(即使这是对const引用的引用).


编辑2:如果你想减少重复的代码,那么不要专门化你的原始类,但使用这个:

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);
};
Run Code Online (Sandbox Code Playgroud)