1

我已经查看了一些类似的问题,但我仍然感到困惑。我试图弄清楚如何在将对象传递给专门的模板函数时显式地(而不是通过编译器优化等)和 C++03 兼容避免复制对象。这是我的测试代码:

#include <iostream>

using namespace std;

struct C
{
  C() { cout << "C()" << endl;  }
  C(const C&) { cout << "C(C)" << endl; }
  ~C() { cout << "~C()" << endl;  }
};

template<class T> void f(T) { cout << "f<T>" << endl; }

// This shows two possible ways, I don't need two overloads
// If I do it like (2) the function is not called, only if I do it like (1)

template<> void f(C c) { cout << "f<C>" << endl; } // (1)

template<> void f(const C& c) { cout << "f<C&>" << endl; } // (2)

int main()
{
    C c;
    f(c);
    return 0;
}

(1) 接受 type 的对象C,并进行复制。这是输出:

C()
C(C)
f<C>
~C()
~C()

因此,我尝试专门使用const C&参数 (2) 来避免这种情况,但这根本行不通(显然原因在这个问题中有解释)。

好吧,我可以“通过指针”,但这有点难看。那么是否有一些技巧可以很好地做到这一点?

编辑:哦,可能我不清楚。我已经有一个模板函数

template<class T> void f(T) {...}

但现在我想专门处理这个函数来接受另一个对象的 const& :

template<> void f(const SpecificObject&) {...}

但只有在我将其定义为时才会调用它

template<> void f(SpecificObject) {...}

基本上我想用这个专业化做的是适应SpecificObject模板界面,比如

template<> void f(SpecificObject obj){ f(obj.Adapted()); } // call the templated version

EDIT2:好的,我可以强制const C&这样调用专业化:

f<const C&>(c);

但是有没有办法让它像这样工作f(c)

EDIT3:如果有人最终会有类似的问题,我终于在另一个问题中找到了这个链接,这很有帮助:http ://www.gotw.ca/publications/mill17.htm

4

6 回答 6

3

您将三个问题混为一谈:模板、重载和参数传递。

只需删除专业化并将参数传递为T const&.

干杯&hth.,

于 2011-02-02T15:12:33.970 回答
2

这会起作用:

int main()
{
    C c;
    f<const C&>(c);
    return 0;
}

您的替代方案:

template<typename T> void f(const boost::reference_wrapper<T const>& c) 
    { cout << "f<boost_const_ref&>" << endl; } 

int main()
{
    C c;
    f(boost::cref(c));
    return 0;
}

实际上,您将使用 boost::reference_wrapper 将引用传递到您想要使用它的位置。您可以使用 get() 来做到这一点,尽管 boost::reference_wrapper 有一个隐式转换回引用,因此您可能无需模板的部分专业化而只需传递boost::cref(c)给常规模板即可。

于 2011-02-02T16:14:19.687 回答
2

你为什么不超载:

void f(const C& c) { cout << "f(const C&)" << endl; }
于 2011-02-02T15:10:39.447 回答
1

Your problem is that the actual parameter c isn't const, so the main template is a better match because it doesn't need to add 'const' to the type. If you try functions that pass by value and by non-const reference, the compiler will tell you that it cannot resolve that difference.

于 2011-02-02T22:12:57.320 回答
1

因此,如果您不总是希望接受 const 引用(这对于基类型 [int、long、float 等] 是合理的),您可以使用一点 boost 魔法。

#include <iostream>
#include <boost/call_traits.hpp>

using namespace std;

struct C
{
  C() { cout << "C()" << endl;  }
  C(const C&) { cout << "C(C)" << endl; }
  //C& operator=(C const&) { cout << "C=C" << endl; return *this; }
  ~C() { cout << "~C()" << endl;  }
};

template<class T> void foo(typename boost::call_traits<T>::param_type inst) { cout << "f<T>" << endl; }
// specialization for calling class C
template<> void foo<C>(boost::call_traits<C>::param_type inst) { cout << "f<C>" << endl; }

int main()
{
  int i = 0;
  foo<int>(i);
  C c;
  foo<C>(c);
  return 0;
}
于 2011-02-02T15:32:09.737 回答
0
#include <iostream>

using namespace std;

struct C
{
  C() { cout << "C()" << endl;  }
  C(const C&) { cout << "C(C)" << endl; }
  ~C() { cout << "~C()" << endl;  }
};

template<class T> void f(const T&) { cout << "f<T>" << endl; }

int main()
{
    C c;
    f(c);
    return 0;
}

这确实可以满足您的需求,但是您必须对传递给函数的所有值使用 const ref。我不知道这是否是你要找的。

于 2011-02-02T15:20:45.073 回答