gpt4 book ai didi

c++ - 编译时运算符[]

转载 作者:行者123 更新时间:2023-12-01 14:53:07 27 4
gpt4 key购买 nike

如何实现包含在 () 或 [] 等运算符中的编译时索引操作?

// works, I already made this
template<int i>
constexpr auto get() const
{
// implementation
// where i is used as a template parameter to other things
}

// no idea how to achieve this
template</*magic*/>
constexpr auto operator[](/*more magic*/) const
{
return get</*use magic*/>();
}

用法

constexpr my_class x;
...= x.get<1>(); // works, kind of ugly
...= x[1]; // doesn't work, parameters aren't compiletime or something

这是我拼凑的一个例子。希望此示例的解决方案与我的实际问题的解决方案相同。

#include <tuple>

class c
{
std::tuple< int, float, char > tuple { 1, 2.f, 'c' };

public:
template< std::size_t i >
constexpr auto & get()
{
return std::get<i>(tuple);
}
//constexpr auto & operator[](std::size_t i)
//{
// return std::get<i>(tuple);
//}
};

int main()
{
constexpr c x;
static_assert( x.get<2>() == 'c' );
static_assert( x.get<1>() - 2.f < .1f );
static_assert( x.get<0>() == 1 );
//static_assert( x[2] == 'c' );
//static_assert( x[1] - 2.f < .1f );
//static_assert( x[0] == 1 );
}

最佳答案

你的 operator[]对于给定的参数类型,必须始终返回相同的类型。解决此问题的方法是使每个参数具有不同的类型。

例如:

template <std::size_t I>
using IndexConstantT = std::integral_constant<std::size_t, I>;

template <std::size_t I>
constexpr IndexConstantT<I> IndexConstant;

class c
{
std::tuple< int, float, char > tuple { 1, 2.f, 'c' };

public:
template <std::size_t i>
constexpr auto& operator[](IndexConstantT<i>) const
{
return std::get<i>(tuple);
}
};

int main()
{
constexpr const c x;
static_assert( x[IndexConstant<2>] == 'c' );
static_assert( x[IndexConstant<1>] - 2.f < .1f );
static_assert( x[IndexConstant<0>] == 1 );
}

Live Demo


正如@NicolBolas 在评论中所建议的那样,为了使语法更好一些,您可以使用 User Defined Literal这样你就可以只使用 2_ic而不是 IndexConstant<2> :

constexpr std::size_t c_to_i(char c)
{
return c - '0';
}

constexpr std::size_t constexpr_pow(std::size_t base, std::size_t exp)
{
std::size_t ret = 1;
for (std::size_t i = 0; i < exp; ++i) {
ret *= base;
}
return ret;
}

template <char... Cs, std::size_t... Is>
constexpr std::size_t to_size_t_impl(std::index_sequence<Is...>)
{
return ((c_to_i(Cs) * constexpr_pow(10, sizeof...(Is) - 1 - Is)) + ...);
}

template <char... Cs>
constexpr std::size_t to_size_t()
{
return to_size_t_impl<Cs...>(std::make_index_sequence<sizeof...(Cs)>{});
}

template <char... Cs>
constexpr auto operator""_ic()
{
return IndexConstant<to_size_t<Cs...>()>;
}

Live Demo

关于c++ - 编译时运算符[],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60983625/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com