首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >概念和模板不再使用g++-11运行。

概念和模板不再使用g++-11运行。
EN

Stack Overflow用户
提问于 2022-08-13 09:12:30
回答 1查看 96关注 0票数 1

以下代码:

代码语言:javascript
复制
#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时,它无法编译,错误如下:

代码语言:javascript
复制
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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-13 10:16:32

没有正确地使用带有模板参数的概念。接受你的代码是完全错误的。它对概念的支持似乎还不够成熟。

如果你有:

代码语言:javascript
复制
template <typename A, typename B, typename C>
concept foo = ...

那么foo的正确用法是使用两个模板类型参数:

代码语言:javascript
复制
template <foo<int, char> Z> class bar ...
template <typename X, foo<X,X> Z> class baz...

否则,这个概念就不知道BC是什么。

参见标准草案中的这篇文章

因此,您不能在概念的中间有一个模板参数包。把它移到最后:

代码语言:javascript
复制
template<typename T, typename KEY, typename JSON_VALUE, typename...KEYS>
concept json_concept = ...

那么像这样的东西应该能起作用:

代码语言:javascript
复制
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);
}

但这只是问题的开始。

你写

代码语言:javascript
复制
t.template get_value<T>(key)

但这毫无意义。T是满足json_concept的类型的名称,在您的示例IJson中。因此,您要将IJson作为IJson::get_value<IJson>的模板参数传递。这不是应该使用get_value的方式。你应该用这样的方法

代码语言:javascript
复制
value = t.template get_value<JSON_VALUE>(key);

目前尚不清楚get_value的另外两个重载在IJson中对应于什么。IJson无法满足json_concepts的所有需求,无论您使用什么语法来表示它们。它只是没有所有所需的重载。

还不清楚如何才能有这样一个参数化的概念,其中只有部分参数参与某些需求。考虑到这一点:

代码语言:javascript
复制
template<json_concept JSON_OPERATOR<???>>
JsonUtil(std::string body, JSON_OPERATOR& json_impl) {
    json_impl.load(body);
}

这个概念要求您提供键、键和值,但是这些都没有在load中使用,在这个上下文中也没有提供它们的好方法。你可以使用一些违约,但这是清除地毯下的污垢。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73342965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档