[英]Is there a way to get the type of a dereferenced value from a dereference-able type?
我在玩 C++ 概念,遇到了一个有趣的问题。 我有以下两个自定义概念:
template<typename T>
concept is_dereferencable = requires (T t) { *t; };
template<typename T>
concept is_printable = requires (T t) { std::cout << t; };
顾名思义,第一个用于确定给定类型是否可以取消引用,而另一个用于检查类型是否支持 output 运算符。 我还有一个名为println
的 function 模板,如下所示:
template<typename T>
void println(const T& t)
{
if constexpr (is_dereferencable<T>) {
if constexpr (is_printable<decltype(*t)>) {
std::cout << *t << '\n';
}
} else if constexpr (is_printable<T>) {
std::cout << t << '\n';
}
}
当且仅当类型T
是可取消引用并且取消引用值的类型是可打印时,它才会打印取消引用值*t
。 因此,例如,我可以将这个 function 模板与类似 std::optional 的东西一起使用:
int main
{
std::optional<std::string> stringOpt {"My Optional String"};
::println(stringOpt);
return 0;
}
这将按预期打印My Optional String
。 虽然这很好,但如果可取消引用的取消引用值的类型不可打印,function 将静默打印任何内容。 因此,对于用户定义的类型Person
,以下内容不会打印任何内容:
struct Person
{
std::string m_name;
explicit Person(const std::string& name) : m_name {name} {}
};
int main
{
std::optional<Person> personOpt {"John Doe"}
::println(personOpt);
return 0;
}
所以我想将上面的编译时if
s 移动到requires
子句本身,以便在这种情况下获得编译时错误。 有没有办法做到这一点? 有没有办法获取给定模板类型T
的取消引用类型? 为了让它更清楚一点,我想要这样的东西:
template<typename T>
requires is_dereferencable<T> && is_printable<decltype(*T)>
void printDereferencable(const T& t)
{
std::cout << *t << '\n';
}
PS:我知道我可以删除嵌套的if
并且在尝试调用 output 运算符时失败不支持它的东西。 但是,我想专门将此编译时错误移至概念中以获得更清晰的错误消息。
你可以使用std::declval
template<typename T>
requires is_dereferencable<const T&> && is_printable<decltype(*std::declval<const T&>())>
void printDereferencable(const T& t)
{
std::cout << *t << '\n';
}
或者你可以写一个is_dereference_printable
概念
template<typename T>
concept is_dereference_printable = requires (T t) { std::cout << *t; };
另一种选择是将约束放在参数之后,这样它就可以访问它们。
template<typename T>
void printDereferencable(const T& t)
requires is_dereferencable<const T&> && is_printable<decltype(*t)>
{
std::cout << *t << '\n';
}
注意:它应该在const T&
上测试,而不是T
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.