![](/img/trans.png)
[英]How to initialize a constexpr std::array with templated constexpr member functions?
[英]Initialize array of pointers to member functions at compile time using constexpr
我想编写以下代码,但出现错误“没有将函数'handler'转换为'void(struct Parser :: *)()”的错误。 我使用带有选项-std = c ++ 14的g ++ 5.3.1
使用-std = 17,我可以使用consrexpr T&std :: array :: operator [](...),但是现在我写了我的类数组。
该代码有什么问题?
#include <cstddef>
template <typename T, size_t _size> struct array {
T elements[_size];
constexpr size_t size() const noexcept { return _size; }
constexpr bool empty() const noexcept { return size() == 0; }
constexpr T& operator[](size_t index) noexcept { return elements[index]; }
};
struct Parser {
template <size_t index> void handler ();
};
template<> void Parser::handler<0> () {
}
template<> void Parser::handler<1> () {
}
constexpr auto createArrayHandlers () {
array <void (Parser::*)(), 2> ans{&Parser::handler<0>, &Parser::handler<1>};
for (size_t i = 0; i < ans.size(); ++i) {
ans[i] = &Parser::handler<0>; //ok
ans[i] = &Parser::handler<i>; //error
}
return ans;
}
constexpr auto table = createArrayHandlers();
int main() {
//table[parse_cmd(read_from_socket())]();
return 0;
}
现在,我用以下代码替换了此代码,但它在运行时执行
std::array<void (Parser::*)(), xxx> table {};
template <size_t i> size_t fillMemeberHandlerArray () {
fillMemeberHandlerArray<i-1>();
table[i] = &Parser::handler<i>;
return i;
}
template<> size_t fillMemeberHandlerArray<0> () {
table[0] = &Parser::handler<0>;
return 0;
}
size_t const initTable = fillMemeberHandlerArray<table.size () - 1>();
#include <utility>
#include <array>
namespace detail {
template<std::size_t... Is>
constexpr auto createArrayHandlers(std::index_sequence<Is...>) noexcept
-> std::array<void(Parser::*)(), sizeof...(Is)>
{
return {{&Parser::handler<Is>...}};
}
}
constexpr auto createArrayHandlers() noexcept
{
return detail::createArrayHandlers(std::make_index_sequence<2>{});
}
constexpr auto table = createArrayHandlers();
由于此操作不使用容器的operator[]
进行填充,因此可以与std::array<>
一起正常工作,而不用自己滚动一个近似值。
模板参数应为常量表达式, i
(来自for
)不是常量表达式。
你可以做
constexpr array<void (Parser::*)(), 2> createArrayHandlers () {
return {{&Parser::handler<0>, &Parser::handler<1>}};
}
或使用std::index_sequence
处理多个编译时间值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.