2013-03-14 33 views
3

我想有通过引用接受临时值和非临时值的模板函数?

template <class T> 
void foo(T &t); 

是能够接受的临时为好,不影响通过参考接受其他的目的和要求他们非const方法。可能在C + + 03?

我意识到我可能迫使用户将其对象的所有方法声明为const,和所有成员mutable然后用const T &t参考,但是这是一个丑陋的解决方法。

+0

假设'foo'试图修改这些临时对象是否正确?为什么? – 2013-03-14 16:59:09

+1

不知何故,你的主题(与“价值”的部分)不符合你的问题描述的其余部分... – PlasmaHH 2013-03-14 16:59:33

+1

在C++ 11这是通用的引用是...但这不是一个功能的存在在C++ 03中 – 2013-03-14 17:14:33

回答

1

您可以创建需要使用const类型的参考,使副本的非const第二功能类型参考。

template <class T> 
void foo (T &t); 

template <class T> 
void foo (const T &x) { 
    T copy(x); 
    foo(copy); 
} 

示范可以发现here

该技术的局限性在于它无法区分临时对象与真实对象const。这样做的后果是,您的原始foo()本来不允许自己通过const对象。这个建议将允许他们,因此你失去了最初提供的一些安全。您可以通过重新命名foo的常量类型版本,使之与foo_for_temp类似,从而弥补这一点。然后,主叫方会知道该功能的意图。

+0

如果非临时性属于“const”限定类型,该怎么办? – 2013-03-14 17:22:16

+1

@AndyProwl:上面的代码无法区分const对象和临时对象。但Irfy的函数原型无论如何都不适用于const限定类型。 – jxh 2013-03-14 17:24:48

+0

确实,这意味着它会编译,而原始函数在用const限定类型的参数调用时(而且应该)不会编译。 – 2013-03-14 17:31:52

0

其中一个,但危险的解决方案是将const T &作为函数参数,然后const_cast <>它到T &。你将有你传递给函数什么要小心,因为它很容易导致未定义行为:

template <class T> 
void foo(const T &ct) 
{ 
    T &t = const_cast<T>(ct); 
    // ... 
} 
4

在C++ 03中,无法推断传递给函数的参数是左值还是右值。

我想这就是为什么你的问题的标题写着“按值接受临时工”的原因:如果这样的机制存在,你可以创建一个函数(模板),其确定的参数类型是否应该T&或基于这些信息,

这正是支持的类型推演机械在C++ 11的作用:

template<typename T> 
void foo(T&& t); 
//  ^^^ 
//  lvalue of type A is passed: T = A&, signature = foo(A& t) 
//  rvalue of type A is passed: T = A, signature = foo(A&& t) 

但正如上面提到的,这是不可能在C++ 03,正是因为它缺乏确定的方式表达式的值类别。

你提到的(强制所有对象有const成员函数)的可能性不是一种解决方法(甚至没有一个丑陋的一个):如果成员函数都是const,这意味着foo()将不需要改变的状态其输入。这又意味着它可能需要一个const&,并解决问题。

您可能是想让那些const成员函数执行const_cast<>以便更改对象的状态,但是您可以再次在foo()中执行相同的操作。这是一个坏主意的原因是,在这两种情况下,您都不能输入foo()输入类型为const的对象,并且您可能不知道这是否是这种情况。

+0

+1的解释,但我接受了一个较不常用的解决方案(没有通过const限定的对象)适用于我的情况。 – Irfy 2013-03-25 12:19:43

+0

我不明白&&的意思,但是随着你的解释,它突然被点击了。非常感谢。 – ioquatix 2017-11-02 21:41:20