空结构或匿名结构作为标签
Empty struct or anonymous struct as tag
将标签类型定义为匿名空结构或定义为空结构在使用上有什么区别吗?
using A = struct {};
struct B {};
在我看来,唯一的区别是 "effective" 类型名称,当使用一种反射时(即 __PRETTY_FUNCTION__
、<cxxabi.h>:abi::__cxa_demangle(typeid().name())
等)。
ADL 适用于两种方式:
namespace ns
{
using A = struct {};
struct B {};
constexpr
bool
adl(A)
{
return true;
}
constexpr
bool
adl(B)
{
return true;
}
}
template< typename type >
constexpr
bool
adl(type)
{
return false;
}
static_assert(adl(ns::A{}));
static_assert(adl(ns::B{}));
除了您已经注意到的不同字符串之外,唯一显着的区别是您可以使用 elaborated-type-specifier 来引用 B
,因此你可以说 struct B b;
而不是 B b;
但你不能使用 struct A a;
因为 A
是一个 typedef-name 而不是 class-name.
然而几乎从来没有一个很好的理由说 struct B
而不是 B
所以在实践中差异并不重要,特别是对于标签类型。
将标签类型定义为匿名空结构或定义为空结构在使用上有什么区别吗?
using A = struct {};
struct B {};
在我看来,唯一的区别是 "effective" 类型名称,当使用一种反射时(即 __PRETTY_FUNCTION__
、<cxxabi.h>:abi::__cxa_demangle(typeid().name())
等)。
ADL 适用于两种方式:
namespace ns
{
using A = struct {};
struct B {};
constexpr
bool
adl(A)
{
return true;
}
constexpr
bool
adl(B)
{
return true;
}
}
template< typename type >
constexpr
bool
adl(type)
{
return false;
}
static_assert(adl(ns::A{}));
static_assert(adl(ns::B{}));
除了您已经注意到的不同字符串之外,唯一显着的区别是您可以使用 elaborated-type-specifier 来引用 B
,因此你可以说 struct B b;
而不是 B b;
但你不能使用 struct A a;
因为 A
是一个 typedef-name 而不是 class-name.
然而几乎从来没有一个很好的理由说 struct B
而不是 B
所以在实践中差异并不重要,特别是对于标签类型。