类 的容器,保留了 cv 限定符和引用?
Container for classes, with cv-qualifier and reference preserved?
我对 C++ 中的 TMP 比较陌生。 我想知道是否有一种方法可以在 c++(17, 没有boost 或 c++20,最好。)
下面是我要找的:
int integer = 0xDEADBEEF;
std::string hello ("hello");
boost::any c (integer);
const int c_deadbeef = integer;
int& cr_deadbeef (integer);
using oneClassContainer = decltype( makeClassContainer(integer, hello, c, c_deadbeef, cr_deadbeef) );
// classContainer<int, std::string, boost::any, const int, int&>
using anotherClassContainer = classContainer<int, const int&, const int>;
// anotherClassContainer is passed to a different function.
// in that function:
getType<anotherClassContainer,0> anotherInt = 3; //int
getType<anotherClassContainer,1> constIntRef (anotherInt); //const int&
getType<anotherClassContainer,2> constIntRef= 3; //const int
我还希望在使用 makeClassContainer
函数参数创建 classContainer 时保留常量。 例如,const int b=3;
然后是 make_tuple(b,1)
call returns a tuple<int,int>
- const
丢失了,因此无论如何使用 make_tuple
在这里都不是一个选项。 (事实上,如果我们能以某种方式保留 make_tuple
中的 const
和 volatile
资格,这将是完美的解决方案)
总而言之,我的问题是是否可以实施以下内容:
- 包含类的结构(不一定是它们的实例化),
- 能够从声明的变量中准确获取 cv 限定和 r/lval 引用限定
- 能够以某种方式return类型,以便它们可以在声明中使用
- 能够传递到不同的上下文(很容易实现,但仍然是一个重要条件)
如果收到答复,我会很高兴。谢谢!
您无法在调用站点中区分 integer
和 cr_deadbeef
,因此您想要的 decltype( makeClassContainer(integer, hello, c, c_deadbeef, cr_deadbeef) )
语法是行不通的。您必须提前申请 decltype
。
或者直接
using my_type_1 = std::tuple<decltype(integer), decltype(hello), decltype(c), decltype(c_deadbeef), decltype(cr_deadbeef)>;
或者通过宏
#include <boost/preprocessor.hpp>
#define ADD_DECLTYPE(a, b, x) decltype(x)
#define MAKE_TYPE_LIST(...) std::tuple< BOOST_PP_TUPLE_ENUM( BOOST_PP_SEQ_TO_TUPLE( BOOST_PP_SEQ_TRANSFORM( ADD_DECLTYPE, 0, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) ) ) >
using my_type_2 = MAKE_TYPE_LIST(integer, hello, c, c_deadbeef, cr_deadbeef);
我对 C++ 中的 TMP 比较陌生。 我想知道是否有一种方法可以在 c++(17, 没有boost 或 c++20,最好。)
下面是我要找的:
int integer = 0xDEADBEEF;
std::string hello ("hello");
boost::any c (integer);
const int c_deadbeef = integer;
int& cr_deadbeef (integer);
using oneClassContainer = decltype( makeClassContainer(integer, hello, c, c_deadbeef, cr_deadbeef) );
// classContainer<int, std::string, boost::any, const int, int&>
using anotherClassContainer = classContainer<int, const int&, const int>;
// anotherClassContainer is passed to a different function.
// in that function:
getType<anotherClassContainer,0> anotherInt = 3; //int
getType<anotherClassContainer,1> constIntRef (anotherInt); //const int&
getType<anotherClassContainer,2> constIntRef= 3; //const int
我还希望在使用 makeClassContainer
函数参数创建 classContainer 时保留常量。 例如,const int b=3;
然后是 make_tuple(b,1)
call returns a tuple<int,int>
- const
丢失了,因此无论如何使用 make_tuple
在这里都不是一个选项。 (事实上,如果我们能以某种方式保留 make_tuple
中的 const
和 volatile
资格,这将是完美的解决方案)
总而言之,我的问题是是否可以实施以下内容:
- 包含类的结构(不一定是它们的实例化),
- 能够从声明的变量中准确获取 cv 限定和 r/lval 引用限定
- 能够以某种方式return类型,以便它们可以在声明中使用
- 能够传递到不同的上下文(很容易实现,但仍然是一个重要条件)
如果收到答复,我会很高兴。谢谢!
您无法在调用站点中区分 integer
和 cr_deadbeef
,因此您想要的 decltype( makeClassContainer(integer, hello, c, c_deadbeef, cr_deadbeef) )
语法是行不通的。您必须提前申请 decltype
。
或者直接
using my_type_1 = std::tuple<decltype(integer), decltype(hello), decltype(c), decltype(c_deadbeef), decltype(cr_deadbeef)>;
或者通过宏
#include <boost/preprocessor.hpp>
#define ADD_DECLTYPE(a, b, x) decltype(x)
#define MAKE_TYPE_LIST(...) std::tuple< BOOST_PP_TUPLE_ENUM( BOOST_PP_SEQ_TO_TUPLE( BOOST_PP_SEQ_TRANSFORM( ADD_DECLTYPE, 0, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) ) ) >
using my_type_2 = MAKE_TYPE_LIST(integer, hello, c, c_deadbeef, cr_deadbeef);