我想在C ++(11)中模拟Python的in
运算符,在Python中使用immedate值。如:
if x in (1, 2, 3): ...
在C ++ 11中,似乎我已经接近能够做到这一点:
if (IsIn(x, { 1, 2, 3 }))
{
}
template<typename Val, Container cont>
bool IsIn(Val const &val, Container const &cont)
{
return boost::find(cont, val) != cont.end();
}
但是(在g ++ - 4.8中)我得到了:
错误:没有匹配函数来调用'IsIn(MyType&amp;,&lt;大括号括号的初始化列表&gt;)'
我知道我可以做到这一点,但这有很多瑕疵:
if (IsIn(x, std::initializer_list<MyType>{1, 2, 3 })) ...
优雅的解决方案是什么?
更新:我对编译时与运行时的想法不够,我仍然无法确定是否有明显的赢家。我的IsIn(x, {})
肯定有更多的运行时循环开销并复制initializer_list值,但也适用于任何容器。 ... == any_of(...
机制肯定会编译为更严格的代码并且不会复制,但只适用于immediates(这是我的原始示例)而不是容器,而sytax(对我来说)似乎不太直接。
因为它是一种平局,所以我将其奖励给贡献者。
感谢大家的讨论!
答案 0 :(得分:3)
解决方案就在我的鼻子底下......
template<typename Val>
bool IsIn(Val val, std::initializer_list<Val> const &cont)
{
return boost::find(cont, val) != cont.end(); // include <boost/range/algorithm.hpp>
// Or if you don't want boost, include <algorithm>
// return std::find(cont.begin(), cont.end(), val) != cont.end();
}
答案 1 :(得分:2)
另一个小想法:
template<typename T, typename ... Args>
struct in_impl
{
in_impl(T const& t, Args const& ... args) : val({t, args ...}) {}
std::array<T, sizeof ...(Args) + 1> val;
};
template<typename T, typename ... Args>
bool operator==(T const& t, in_impl<T, Args ...> const& in)
{
return std::find(std::begin(in.val), std::end(in.val), t) != std::end(in.val);
}
template<typename T, typename ... Args>
auto in(T const& t, Args const& ... args)
{
return in_impl<T, Args ...>(t, args ...);
}
这可以用作
int main()
{
if(1 == in(1,2,3) )
{
std::cout<<"1 is in"<<std::endl;
}
}
在获得领先类型T
时可以更加小心,但这个想法应该变得清晰。
答案 2 :(得分:1)
我为无耻的插件道歉,但我认为它解决了OP的问题。
您可以使用this library:
#include "smart_conditions.hpp"
using namespace smart_conditions;
// ...
if (x == any_of (1, 2, 3))
{
// ...
}
它支持其他关系运算符,如果所有操作数在编译时都已知,在编译时工作(constexpr
),它使无副本 。另外,适用于混合类型,这意味着if (std::string("x") == any_of ("x", "y"))
编译得很好。
答案 3 :(得分:0)
有两种情况,一种情况可以拨打std::find(container.begin(), container.end(), value)
,另一种情况可以拨打template<typename IteratorType, typename Type>
bool
contains ( IteratorType first, IteratorType last, Type const& value )
{
return std::find ( first, last, value ) != last;
}
template <template <typename, typename ...> class ContainerType, typename KeyType, typename... Types>
bool
contains_key
( ContainerType <KeyType, Types ...> const& container
, KeyType const& key
)
{
return container.find ( key ) != container.end ( );
}
:
User.objects.filter(username=username).update(is_staff=True)