从特征获取常量或非常量引用类型
我正在编写一个函子 F,它接受 void (*func)(T) 类型的函数和 func 的参数 arg。
template<typename T>
void F(void (*func)(T), WhatTypeHere? arg)
{
func(arg);
}
然后函子 F 使用 arg 调用 func。我希望 F 不要复制 arg,只是将其作为引用传递。但是我不能简单地写“void F(void (*func)(T), T&)”,因为 T 可以是引用。所以我试图编写一个特征,它允许获得正确的 T 引用类型:
T -> T&
T& -> T&
const T -> const T&
const T& -> const T&
我想出了这样的东西:
template<typename T>
struct type_op
{
typedef T& valid_ref_type;
};
template<typename T>
struct type_op<T&>
{
typedef typename type_op<T>::valid_ref_type valid_ref_type;
};
template<typename T>
struct type_op<const T>
{
typedef const T& valid_ref_type;
};
template<typename T>
struct type_op<const T&>
{
typedef const T& valid_ref_type;
};
template<typename T>
void F(void (*func)(T), typename type_op<T>::valid_ref_type arg)
{
func(arg);
}
不起作用
void a(int x) { std::cout << x << std::endl; }
F(&a, 7);
这对于给出错误 : 类型“int&”的非常量引用的初始化无效从类型为 'int' 的临时变量传递 'void F(void (*)(T), typename type_op::valid_ref_type) [with T = int]' 的参数 2
如何使此特征发挥作用?
I am writing a functor F which takes function of type void (*func)(T) and func's argument arg.
template<typename T>
void F(void (*func)(T), WhatTypeHere? arg)
{
func(arg);
}
Then functor F calls func with arg. I would like F not to copy arg, just to pass it as reference. But then I cannot simply write "void F(void (*func)(T), T&)" because T could be a reference. So I am trying to write a trait, which allows to get proper reference type of T:
T -> T&
T& -> T&
const T -> const T&
const T& -> const T&
I come up with something like this:
template<typename T>
struct type_op
{
typedef T& valid_ref_type;
};
template<typename T>
struct type_op<T&>
{
typedef typename type_op<T>::valid_ref_type valid_ref_type;
};
template<typename T>
struct type_op<const T>
{
typedef const T& valid_ref_type;
};
template<typename T>
struct type_op<const T&>
{
typedef const T& valid_ref_type;
};
template<typename T>
void F(void (*func)(T), typename type_op<T>::valid_ref_type arg)
{
func(arg);
}
Which doesn't work for example for
void a(int x) { std::cout << x << std::endl; }
F(&a, 7);
Giving error:
invalid initialization of non-const reference of type ‘int&’ from a temporary of type ‘int’ in passing argument 2 of ‘void F(void (*)(T), typename type_op::valid_ref_type) [with T = int]’
How to get this trait to work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的映射很接近,您实际上希望 T 映射到 T const&同样:
请注意,参数类型为 T const 的函数的签名为 T! const 是一个实现细节:
Your mapping was close, you actually want T mapped to T const& too:
Note that functions having a parameter type of T const have a signature of T! The const is an implementation detail:
您所需要做的就是删除引用:
然后再次添加它,如下所示:
您的函数应声明如下:
All you need is to remove a reference:
Then add it again as follows:
Your function should be declared as follows:
我的想法有点模糊,但我认为 boost(可能是 boost::bind)通过仅提供 const T& 特征并需要使用 ref(x)< 来解决这个问题/code> 指示非常量引用。
It's a bit vague in my mind, but I think that boost (maybe boost::bind) solves this by only providing
const T&
traits, and requiring the use ofref(x)
to indicate a non-const reference.您还可以使用
add_reference
来实现您需要的类型映射。You could also use
add_reference
from Boost.TypeTraits to achieve the type-mapping you need.