假设我有一些类型的对象T,我想把它放到一个引用包装器中:
int a = 5, b = 7;
std::reference_wrapper<int> p(a), q(b); // or "auto p = std::ref(a)"
Run Code Online (Sandbox Code Playgroud)
现在我可以很容易地说if (p < q),因为引用包装器已转换为其包装类型.一切都很开心,我可以处理一组参考包装器,就像它们是原始对象一样.
(正如下面链接的问题所示,这可以是生成现有集合的备用视图的有用方法,可以随意重新排列,而不会产生完整副本的成本,以及维护原始集合的更新完整性. )
但是,对于某些类,这不起作用:
std::string s1 = "hello", s2 = "world";
std::reference_wrapper<std::string> t1(s1), t2(s2);
return t1 < t2; // ERROR
Run Code Online (Sandbox Code Playgroud)
我的解决方法是在这个答案中定义一个谓词*; 但我的问题是:
为什么以及何时可以将运算符应用于引用包装器并透明地使用包装类型的运算符?为什么会失败std::string?它与std::string模板实例的事实有什么关系?
*)更新:根据答案,似乎使用std::less<T>()是一般解决方案.
c++ templates implicit-conversion reference-wrapper template-argument-deduction
没有例子,这个问题几乎没有意义.所以这就是我想要做的.
通常,C++允许以下内容:
template<class T, class U, T t, U u>
void func() {}
func<char, int, 'A', 10>();
Run Code Online (Sandbox Code Playgroud)
但似乎它的自然变量扩展不起作用.
template<class...T, T... t>
void func() {}
func<char, int, 'A', 10>();
Run Code Online (Sandbox Code Playgroud)
clang和g ++ 4.7都拒绝上述代码.实例化完成后会显示错误.在我看来,应该明确地解析两个可变列表,因为第一个具有类型而另一个仅具有整数值.
如果上述内容无效,我认为以下内容也不起作用.
template <class Ret, class... Args, Ret (*func)(Args...)>
class Foo {};
Run Code Online (Sandbox Code Playgroud)
我认为Foo模板是一个非常有用的东西.
有没有办法将c ++ 0x lambda的签名,结果和参数类型推断为Boost.MPL序列,例如boost::mpl::vector?例如,对于lambda
[]( float a, int b ) -> void { std::cout << a << b << std::endl; }
Run Code Online (Sandbox Code Playgroud)
我想得到一个boost::mpl::vector<void,float,int>.