gpt4 book ai didi

c++ - 区分值模板类和左值模板类的正确特化是什么?

转载 作者:行者123 更新时间:2023-12-03 07:00:38 25 4
gpt4 key购买 nike

我需要进行模板特化,以区分具有(仅)值参数的模板类,如下所示:

template<auto ... __vz>
struct values{};
和一个带有(仅)引用参数的模板类,如下所示:
template<auto& ... __lvz>
struct lvalues{};
但是通过以下特化我没有成功:
template<typename>
struct is_values{
static constexpr bool value = false;
};
template<template<auto ...>class __m, auto ... __vz>
struct is_values<__m<__vz ...> >{
static constexpr bool value = true;
};

template<typename>
struct is_lvalues{
static constexpr bool value = false;
};
template<template<auto& ...>class __m, auto& ... __vz>
struct is_lvalues<__m<__vz ...> >{
static constexpr bool value = true;
};
当它们进行如下测试时:
const int a = 1;
const int b = 2;
const int c = 3;

int main()
{
std::cout << is_values<lvalues<a,b,c> >::value <<std::endl; // wrong result
std::cout << is_lvalues<values<1,2,3> >::value <<std::endl; // causes error
}
其中一个给出了错误的结果,一个给出了以下错误:
test.cpp: In instantiation of ‘struct is_lvalues<values<1, 2, 3> >’:
test.cpp:51:41: required from here
test.cpp:32:34: error: initializing ‘int&’ with ‘int’ in converted constant expression does not bind directly
32 | struct is_lvalues<__m<__vz ...> >{
| ^
test.cpp:32:34: error: could not convert ‘1’ from ‘int’ to ‘int&’
test.cpp:32:34: error: initializing ‘int&’ with ‘int’ in converted constant expression does not bind directly
test.cpp:32:34: error: could not convert ‘2’ from ‘int’ to ‘int&’
test.cpp:32:34: error: initializing ‘int&’ with ‘int’ in converted constant expression does not bind directly
test.cpp:32:34: error: could not convert ‘3’ from ‘int’ to ‘int&’
test.cpp:33:24: error: initializing ‘int&’ with ‘int’ in converted constant expression does not bind directly
33 | static constexpr bool value = true;
| ^~~~~
test.cpp:33:24: error: could not convert ‘1’ from ‘int’ to ‘int&’
test.cpp:33:24: error: initializing ‘int&’ with ‘int’ in converted constant expression does not bind directly
test.cpp:33:24: error: could not convert ‘2’ from ‘int’ to ‘int&’
test.cpp:33:24: error: initializing ‘int&’ with ‘int’ in converted constant expression does not bind directly
test.cpp:33:24: error: could not convert ‘3’ from ‘int’ to ‘int&’
test.cpp: In function ‘int main()’:
test.cpp:51:43: error: ‘value’ is not a member of ‘is_lvalues<values<1, 2, 3> >’
51 | std::cout << is_lvalues<values<1,2,3> >::value <<std::endl; // causes error
| ^~~~~
make: *** [src/subdir.mk:20: src/test.o] Error 1
"make all" terminated with exit code 2. Build might be incomplete.

12:14:37 Build Failed. 14 errors, 0 warnings. (took 677ms)

到目前为止,我只在以下专业方面取​​得了成功:
template<auto ... __vz>
struct is_values<values<__vz ...> >{
static constexpr bool value = true;
};
template<auto& ... __vz>
struct is_lvalues<lvalues<__vz ...> >{
static constexpr bool value = true;
};
但这些不是我们所希望的,因为它们只检测到 values 产生的类型。和 lvalues不是任何其他具有不同名称的类似模板。
那么什么是正确的专业呢?

最佳答案

如果您正在为类型解决此问题,您可以使用
std::is_lvalue_reference 为单一类型执行此操作。由于您似乎使用的是 C++17,因此您可以使用折叠表达式将其应用于参数包:

template <typename... Ts>
using are_types_lvalues = std::integral_constant<bool, (std::is_lvalue_reference_v<Ts> && ...)>;

template <typename... Ts>
using are_types_values = std::integral_constant<bool, !(std::is_reference_v<Ts> || ...)>;
如果您可以测试类型,则可以使用 decltype获取非类型参数的类型,而不用担心强制参数绑定(bind)到 autoauto& ...
template<typename>
struct are_values : std::false_type {};
template<template<auto ...>class __m, auto ... __vz>
struct are_values<__m<__vz ...>> : std::integral_constant<bool, !(std::is_reference_v<decltype(__vz)> || ...)> {};

template<typename>
struct are_lvalues : std::false_type {};
template<template<auto ...>class __m, auto ... __vz>
struct are_lvalues<__m<__vz ...>> : std::integral_constant<bool, (std::is_lvalue_reference_v<decltype(__vz)> && ...)> {};
用法:
template<auto... __vz>
struct values{};

template<auto& ... __lvz>
struct lvalues{};

const int a = 1;
const int b = 2;
const int c = 3;

static_assert(are_values<values<1,2,3>>::value, "");
static_assert(!are_values<lvalues<a,b,c>>::value, "");
static_assert(!are_lvalues<values<1,2,3>>::value, "");
static_assert(are_lvalues<lvalues<a,b,c>>::value, "");
演示:
https://godbolt.org/z/KTh9Wj

关于c++ - 区分值模板类和左值模板类的正确特化是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64133964/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com