提问人:digito_evo 提问时间:9/17/2022 更新时间:9/17/2022 访问量:254
为什么 decltype(*this)::value_type 编译不?[复制]
Why doesn't decltype(*this)::value_type compile? [duplicate]
问:
为什么不编译?它显示一条错误消息:decltype(*this)
error: 'value_type' is not a member of 'const Foo<char>&'
那么,在下面的程序中无法编译的原因究竟是什么:decltype( *this )::value_type
#include <iostream>
#include <vector>
#include <type_traits>
template <typename charT>
struct Foo
{
using value_type = charT;
std::vector<value_type> vec;
void print( ) const;
};
template <typename charT>
void Foo<charT>::print( ) const
{
using Foo_t = std::remove_reference_t<decltype( *this )>;
// `decltype( *this )::value_type` does not compile
if constexpr ( std::is_same_v< typename Foo_t::value_type,
decltype( std::cout )::char_type > )
{
// logic
}
else if constexpr ( std::is_same_v< typename Foo_t::value_type,
decltype( std::wcout )::char_type > )
{
// logic
}
else
{
static_assert( std::is_same_v< typename Foo_t::value_type,
decltype( std::cout )::char_type > ||
std::is_same_v< typename Foo_t::value_type,
decltype( std::wcout )::char_type >,
"character type not supported" );
}
}
int main( )
{
#define IS_CHAR 1
#if IS_CHAR == 1
using FooChar = Foo<char>;
FooChar foo;
foo.vec.resize( 10, '$' );
#else
using FooWideChar = Foo<wchar_t>;
FooWideChar foo;
foo.vec.resize( 10, L'#' );
#endif
foo.print( );
}
指针有什么特别之处?为什么删除引用会使其编译?在上面的片段中一切正常。但是,如果我用更具可读性的替换,它将无法编译。因此,我尝试了一下运气,并设法提出了上述不太简单(且不太直观)的解决方案:this
std::remove_reference_t
typename Foo_t::value_type
decltype( *this )::value_type
std::remove_reference_t
using Foo_t = std::remove_reference_t<decltype( *this )>;
// and then inside the std::is_same_v
std::is_same_v< typename Foo_t::value_type, /* etc */ >
// ...
我知道有更简洁的替代方案,例如 甚至,但我发现这种方法更不言自明。还有其他解决方案吗?std::is_same_v< Foo<charT>::value_type,
std::is_same_v< charT,
decltype
答:
0赞
Chris Dodd
9/17/2022
#1
将一元应用于指针的结果是指向值的引用(左值引用),而不是指向值的副本。因此(或对于任何指针类型)将始终是引用类型。没什么特别的。operator*
decltype(*this)
decltype(*foo)
this
评论
0赞
François Andrieux
9/17/2022
我不认为这那么容易。指针的间接是指“左值引用表达式指向的对象或函数”,这与引用不同。编辑:查看副本。
0赞
Chris Dodd
9/17/2022
“左值”是(只是)C++中的一种引用(还有其他类型的引用)。
0赞
François Andrieux
9/17/2022
左值引用是一种引用。左值表达式是不同的。某些东西可以是没有引用类型的左值表达式。如果我们以后使用表达式,则表达式是左值表达式,不使用任何引用类型。int i = 0;
i;
1赞
NathanOliver
9/17/2022
@ChrisDodd 是 中的声明符。它是 中的左值表达式。我的评论中有 2 行代码。foo
int foo = 42;
foo;
1赞
NathanOliver
9/17/2022
不,它没有。 没有被声明为引用,并且是 ,而不是 : coliru.stacked-crooked.com/a/330c00696e7cfbaffoo
decltype(foo)
int
int&
评论
T
和是不同的类型,就像 和 一样。指针和引用没有指向/引用的事物的成员。T&
T
T*
decltype(*this)
*this
*this
decltype