Skip to content

Document a nice advantage of tuplet over std::tuple - allowed to be passed as non-type template argument since it's consexpr #35

Description

@Tal500

Thanks for this awesome one header project!
Hope that this project is still alive :-)

I was trying to find a solution for a problem that wasn't described in this project README, but this problem is solved.
I believe that these issue with std::tuple should be stated in the README.

For terrible reasons, since std::tuple isn't trivially copyable, std::tuple couldn't be accepted as a non-type template argument.
But this library has no such problem, and it is allowed!

What I mean is that the following code is legal:

template <tuplet::tuple<int, int> t>
consteval int func_tuplet() {
    return get<1>(t) + 1;
}

void test_tuplet() {
    constexpr tuplet::tuple t {1, 2};
    func_tuplet<t>();
}

While this code fails to compile:

template <std::tuple<int, int> t>
consteval int func_std() {
    return std::get<1>(t) + 1;
}

void test_std() {
    constexpr std::tuple t {1, 2};
    func_std<t>();
}

GCC calls this std::tuple<int, int> as "incomplete type", following the explanation I mentioned before (from compiler explorer, x86-64 GCC, with the flag -std=c++23):

<source>:1504:32: error: invalid use of incomplete type 'class std::tuple<int, int>'
 1504 | template <std::tuple<int, int> t>
      |                                ^
In file included from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/utility:69,
                 from <source>:6:
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_pair.h:90:11: note: declaration of 'class std::tuple<int, int>'
   90 |     class tuple;
      |           ^~~~~
<source>: In function 'void test_std()':
<source>:1510:33: error: class template argument deduction failed:
 1510 |     constexpr std::tuple t {1, 2};
      |                                 ^
<source>:1510:33: error: no matching function for call to 'tuple(int, int)'
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_pair.h:90:11: note: candidate: 'template<class ...> tuple()-> std::tuple< <template-parameter-1-1> >'
   90 |     class tuple;
      |           ^~~~~
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_pair.h:90:11: note:   template argument deduction/substitution failed:
<source>:1510:33: note:   candidate expects 0 arguments, 2 provided
 1510 |     constexpr std::tuple t {1, 2};
      |                                 ^
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_pair.h:90:11: note: candidate: 'template<class ...> tuple(std::tuple< <template-parameter-1-1> >)-> std::tuple< <template-parameter-1-1> >'
   90 |     class tuple;
      |           ^~~~~
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_pair.h:90:11: note:   template argument deduction/substitution failed:
<source>:1510:33: note:   mismatched types 'std::tuple< <template-parameter-1-1> >' and 'int'
 1510 |     constexpr std::tuple t {1, 2};
      |                                 ^
<source>:1511:16: error: no matching function for call to 'func_std<t>()'
 1511 |     func_std<t>();
      |     ~~~~~~~~~~~^~
<source>:1505:15: note: candidate: 'template<<typeprefixerror>t> consteval int func_std()'
 1505 | consteval int func_std() {
      |               ^~~~~~~~
<source>:1505:15: note:   template argument deduction/substitution failed:
Compiler returned: 1

More generally, std::tuple cannot be a consexpr.
Here is the cpp test function:

void test_std_tuple_constexpr() {
    constexpr std::tuple<int, int> t {1, 2};
}

And here is the same GCC output:

<source>: In function 'void test_std_tuple_constexpr()':
<source>:1495:36: error: variable 'constexpr const std::tuple<int, int> t' has initializer but incomplete type
 1495 |     constexpr std::tuple<int, int> t {1, 2};
      |                                    ^
Compiler returned: 1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions