以下代码:
#include <cstdio>
#include <string>
#include <concepts>
template<typename T, typename KEY, typename JSON_VALUE, typename...KEYS>
concept json_concept = requires(T t, int index, std::string& json_body, KEY key, JSON_VALUE value, KEYS... keys)
{
{ t.template get_value<T>(keys...) } -> std::same_as<T>;
{ t.template get_value<T>(key) } -> std::same_as<T>;
{ t.template get_value<T>(index, keys...) } -> std::same_as<T>;
{ t.set_cache(keys...) } -> std::same_as<void>;
{ t.get_list_size() } -> std::same_as<int>;
{ t.init_cache() } -> std::same_as<void>;
{ t.load(json_body) } -> std::same_as<void>;
{ t.contains(key) } -> std::same_as<bool>;
{ t.set_root_value(value) } -> std::same_as<void>;
{ t.release() } -> std::same_as<JSON_VALUE>;
};
class JsonUtil {
public:
template<json_concept JSON_OPERATOR>
JsonUtil(std::string body, JSON_OPERATOR& json_impl) {
json_impl.load(body);
}
template<typename T, json_concept JSON_OPERATOR, typename KEY>
T get_value(JSON_OPERATOR& json_impl, KEY&& key) {
return json_impl.template get_value<T>(std::forward<KEY>(key));
}
template<typename T, json_concept JSON_OPERATOR, typename... KEYS>
T get_value(JSON_OPERATOR& json_impl, KEYS&& ... keys) {
return json_impl.template get_value<T>(std::forward<KEYS>(keys)...);
}
template<json_concept JSON_OPERATOR, typename... KEYS>
void set_cache(JSON_OPERATOR& json_impl, KEYS&& ... keys) {
json_impl.set_cache(std::forward<KEYS>(keys)...);
}
template<json_concept JSON_OPERATOR>
void init_cache(JSON_OPERATOR& json_impl) {
json_impl.init_cache();
}
};
class IJson {
public:
template<typename T, typename KEY>
T get_value(KEY&& key) {
return T();
}
void load(std::string body) { };
};
int main()
{
IJson dd = IJson{};
JsonUtil jsoncpp(std::string("dummy"), dd);
}这段代码过去常与clang++-10一起运行。当我开始使用g++-11时,它无法编译,错误如下:
conc.cpp:26:14: error: wrong number of template arguments (1, should be at least 3)
26 | template<json_concept JSON_OPERATOR>
| ^~~~~~~~~~~~~~~~~~~
conc.cpp:4:9: note: provided for ‘template<class T, class ... KEYS, class KEY, class JSON_VALUE> concept json_concept’
4 | concept json_concept = requires(T t, int index, std::string& json_body, KEYS... keys, KEY key, JSON_VALUE value)有什么问题,我该怎么解决呢?即使不是所有的模板参数都会被使用,每次我调用概念的一个函数部分时,这个解决方案真的可以提供所有的模板类型吗?
g++版本为11.1.0
发布于 2022-08-13 10:16:32
没有正确地使用带有模板参数的概念。接受你的代码是完全错误的。它对概念的支持似乎还不够成熟。
如果你有:
template <typename A, typename B, typename C>
concept foo = ...那么foo的正确用法是使用两个模板类型参数:
template <foo<int, char> Z> class bar ...
template <typename X, foo<X,X> Z> class baz...否则,这个概念就不知道B和C是什么。
参见标准草案中的这篇文章。
因此,您不能在概念的中间有一个模板参数包。把它移到最后:
template<typename T, typename KEY, typename JSON_VALUE, typename...KEYS>
concept json_concept = ...那么像这样的东西应该能起作用:
template<typename K, typename V, typename ... Ks,
json_concept<K, V, Ks> JSON_OPERATOR>
JsonUtil(std::string body, JSON_OPERATOR& json_impl) {
json_impl.load(body);
}但这只是问题的开始。
你写
t.template get_value<T>(key)但这毫无意义。T是满足json_concept的类型的名称,在您的示例IJson中。因此,您要将IJson作为IJson::get_value<IJson>的模板参数传递。这不是应该使用get_value的方式。你应该用这样的方法
value = t.template get_value<JSON_VALUE>(key);目前尚不清楚get_value的另外两个重载在IJson中对应于什么。IJson无法满足json_concepts的所有需求,无论您使用什么语法来表示它们。它只是没有所有所需的重载。
还不清楚如何才能有这样一个参数化的概念,其中只有部分参数参与某些需求。考虑到这一点:
template<json_concept JSON_OPERATOR<???>>
JsonUtil(std::string body, JSON_OPERATOR& json_impl) {
json_impl.load(body);
}这个概念要求您提供键、键和值,但是这些都没有在load中使用,在这个上下文中也没有提供它们的好方法。你可以使用一些违约,但这是清除地毯下的污垢。
https://stackoverflow.com/questions/73342965
复制相似问题