te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>c++ - Structured binding declaration for class inherited from tuple - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Structured binding declaration for class inherited from tuple - Stack Overflow

programmeradmin3浏览0评论

I have a class inherited from standard tuple:

#include <concepts>
#include <cstdint>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>

template< typename ... Args >
class Identifier: public std::tuple< Args... >
{
public:
   Identifier( Args... args ) requires( sizeof...( Args ) != 0 ) : std::tuple< Args... >( std::move( args )... )
   {}

   Identifier( std::tuple< Args... > tuple ):std::tuple< Args... >( tuple )
   {}

   Identifier()
   {}

   Identifier(std::convertible_to<std::tuple<Args...>> auto&& identifier)
           : std::tuple<Args...>(std::forward<decltype(identifier)>(identifier)) {}
};

int main()
{
   Identifier<std::wstring, std::int64_t>  id(L"id", 10);
   auto& [ str_id, num_id ] = id;

   std::tuple< std::wstring, int64_t > tuple_id(L"id", 10);
   auto& [ str_t_id, num_t_id ] = tuple_id;

   return 0;
}

in line

auto& [ str_id, num_id ] = item;

I got error Type 'Identifier<std::wstring, int64_t>' (aka 'Identifier<basic_string<wchar_t>, long long>') decomposes into 1 element, but 2 names were provided

but the same code for tuple variable its ok

auto& [ str_t_id, num_t_id ] = tuple_id;

What I have to do to support structured binding for class Identifier ?

I have a class inherited from standard tuple:

#include <concepts>
#include <cstdint>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>

template< typename ... Args >
class Identifier: public std::tuple< Args... >
{
public:
   Identifier( Args... args ) requires( sizeof...( Args ) != 0 ) : std::tuple< Args... >( std::move( args )... )
   {}

   Identifier( std::tuple< Args... > tuple ):std::tuple< Args... >( tuple )
   {}

   Identifier()
   {}

   Identifier(std::convertible_to<std::tuple<Args...>> auto&& identifier)
           : std::tuple<Args...>(std::forward<decltype(identifier)>(identifier)) {}
};

int main()
{
   Identifier<std::wstring, std::int64_t>  id(L"id", 10);
   auto& [ str_id, num_id ] = id;

   std::tuple< std::wstring, int64_t > tuple_id(L"id", 10);
   auto& [ str_t_id, num_t_id ] = tuple_id;

   return 0;
}

in line

auto& [ str_id, num_id ] = item;

I got error Type 'Identifier<std::wstring, int64_t>' (aka 'Identifier<basic_string<wchar_t>, long long>') decomposes into 1 element, but 2 names were provided

but the same code for tuple variable its ok

auto& [ str_t_id, num_t_id ] = tuple_id;

What I have to do to support structured binding for class Identifier ?

Share Improve this question edited Feb 17 at 21:51 Ted Lyngmo 117k7 gold badges82 silver badges132 bronze badges asked Feb 17 at 21:28 Vladimir ShttlVladimir Shttl 613 bronze badges 4
  • By item you mean id, right? It's helpful to be certain the error matches the code exactly. – Useless Commented Feb 17 at 21:57
  • (also you didn't need to edit in return 0, it was fine without. Just FYI) – Useless Commented Feb 17 at 21:58
  • 1 Maybe a dup – edrezen Commented Feb 17 at 22:14
  • Good spot, it is. Unfortunately it's a much worse title and the accepted answer is ... unfortunate. – Useless Commented Feb 17 at 22:25
Add a comment  | 

3 Answers 3

Reset to default 0

I can't see a direct duplicate for this, although there are overlapping questions on tuple-like binding protocol.

For this case (not an array, not a simple aggregate: specifically case 2 here),

  • The expression std::tuple_size<E>::value must be a well-formed integral constant expression,

but it isn't. Having std::tuple_size<std::tuple<...>> defined doesn't help a subclass, because implicit conversions don't happen here.

You'll need to specialize it yourself.

  • For each structured binding, a variable whose type is "reference to std::tuple_element<I, E>::type" is introduced:...

You'll need to specialize this too. They can both just forward to the std::tuple versions.

You also need

  • e.get<I>(), if lookup for the identifier get in the scope of E by class member access lookup finds at least one declaration ...
  • Otherwise, get<I>(e), where get is looked up by argument-dependent lookup only, ignoring non-ADL lookup.

But here we finally have ADL doing the work of finding the normal std::get for us.

Structured binding won't work with std::tuple and a template parameter pack

You need to specialize std::tuple and implement tuple_size and tuple_element

Examples here: Direct initialization fails with class derived from std::tuple, while it works for std::pair

Implemented the classes tuple_size and tuple_element and it worked

template < class... Args >
struct std::tuple_size< sbis::IdentifierType< Args...> > : public std::integral_constant< size_t, sizeof...( Args ) > {};

template< std::size_t I, class... Args >
class std::tuple_element< I, sbis::IdentifierType< Args... > > : public tuple_element< I, std::tuple< Args... > >{};
发布评论

评论列表(0)

  1. 暂无评论