Der folgende Code:var in seinem eigenen initializer verwendete
auto getConnection(const std::string &name) {
constexpr const std::size_t id{findFactoryId(_factories, name)};
const auto factory = std::get<std::integral_constant<std::size_t, id>{}>(_factories).second;
for (auto &connection : _connections[id])
if (connection.first) {
connection.first = false;
decltype(factory()) &res = std::experimental::any_cast(connection.second);
return res;
}
_connections[id].emplace_back(std::make_pair<bool, std::experimental::any>(false, factory()));
decltype(factory()) &res = std::experimental::any_cast(_connections[id].back().second);
return res;
}
mit Klirren ++ kompilieren, aber mit g ++ gibt diesen Fehler:
In file included from main.cpp:2:0:
src/core/include/connectionpool.h: Dans la fonction membre « auto Core::ConnectionPool<Connectors>::getConnection(const string&) »:
src/core/include/connectionpool.h:28:79: erreur : the value of « id » is not usable in a constant expression
const auto factory = std::get<std::integral_constant<std::size_t, id>{}>(_factories).second;
^~
src/core/include/connectionpool.h:27:41: note : « id » used in its own initializer
constexpr const std::size_t id{findFactoryId(_factories, name)};
^~
src/core/include/connectionpool.h:28:81: erreur : the value of « id » is not usable in a constant expression
const auto factory = std::get<std::integral_constant<std::size_t, id>{}>(_factories).second;
^
src/core/include/connectionpool.h:27:41: note : « id » used in its own initializer
constexpr const std::size_t id{findFactoryId(_factories, name)};
^~
src/core/include/connectionpool.h:28:81: note : in template argument for type « unsigned int »
const auto factory = std::get<std::integral_constant<std::size_t, id>{}>(_factories).second;
^
ich jenen Befehl zu kompilieren:
(clan)g++ -std=c++14 -O2 -Wall -pedantic -Wextra main.cpp
mit g++ v6.3.1
und clang++ v3.9.1
Der einzige Link, der meinem Problem entspricht, ist ein Fehlerbericht für gcc4.9 (der gelöst ist): https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59937.
Ein minimales Arbeitsbeispiel ist verfügbar here.
Von was ich von gcc
Fehlermeldung verstanden habe, sollte ich keinen Fehler haben: id
wird nicht verwendet, um sich selbst zu initialisieren.
Sollte dieser Code einen Fehler ergeben oder nicht?
Wenn es einen Fehler auslösen sollte, was könnte ich tun, um den Fehler zu beheben?
Vielen Dank für Ihre Antworten.
Der vollständige Code:
#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <functional>
#include <utility>
#include <type_traits>
#include <tuple>
#include <experimental/any>
template <class F, class... Ts>
constexpr void for_each_in_tuple(const std::tuple<Ts...> &tuple, F f) {
for_each_in_tuple(tuple, f, std::make_index_sequence<sizeof...(Ts)>());
}
template <class F, class... Ts, std::size_t... Is>
constexpr void for_each_in_tuple(const std::tuple<Ts...> &tuple, F f, std::index_sequence<Is...>) {
using expander = int[];
(void) expander{0, ((void)f(Is, std::get<Is>(tuple)), 0)...};
}
template <typename... Connectors>
class ConnectionPool {
public:
auto getConnection(const std::string &name) {
constexpr const std::size_t id{findFactoryId(_factories, name)};
const auto factory = std::get<std::integral_constant<std::size_t, id>{}>(_factories).second;
return factory();
}
private:
struct foo {
constexpr foo(std::size_t &i, const std::string &name) : i(i), name(name) {}
template <class T>
constexpr void operator()(const std::size_t is, const T pair) {
i = name == pair.first ? is : i;
}
std::size_t &i;
const std::string &name;
};
template <class Tuple>
static constexpr std::size_t findFactoryId(Tuple &tup, const std::string &name) {
std::size_t i = 0;
for_each_in_tuple(tup, foo(i, name));
return i;
}
std::tuple<std::pair<std::string, std::function<Connectors()>>...> _factories;
};
int main()
{
return 0;
}
EDIT
ändern Link zu minimalen Arbeitsbeispiel: eine Funktion fehlte.
EDIT 2
hinzufügen minimales Arbeitsbeispiel in der Post
Der Fehler ist ziemlich klar, 'findFactoryId()' 'nicht constexpr' von gcc Sicht liefert, sollten Sie besser schreiben ihren Körper hier. – VTT
Können Sie das Codebeispiel in [MCVE] vereinfachen? –