考虑以下代码,尝试确定是否存在嵌套的typedef。
#include<type_traits>
struct foo;// incomplete type
template<class T>
struct seq
{
using value_type = T;
};
struct no_type{};
template<class T>
struct check_type : std::true_type{};
template<>
struct check_type<no_type> :std::false_type{};
template<class T>
struct has_value_type
{
template<class U>
static auto check(U const&)-> typename U:: value_type;
static auto check(...)->no_type;
static bool const value = check_type<decltype(check(std::declval<T>()))>::value;
using type = has_value_type;
};
int main()
{
char c[has_value_type<seq<foo>>::value?1:-1];
(void)c;
}
现在调用has_value_type<seq>::value
会导致编译错误,因为无效使用了不完整类型seq<foo>::value_type
。
decltype
需要表达式中的完整类型吗?如果没有,我该如何删除错误?我正在使用gcc 4.7进行编译。
答案 0 :(得分:3)
您的代码是有效的C ++ 11,它定义了一个出现为decltype操作数的顶级函数调用,即使调用是prvalue也不会引入临时函数。
此规则专门用于使您的代码有效并防止实例化返回类型(如果它是类模板特化),否则需要确定析构函数的访问限制。
答案 1 :(得分:2)
decltype
需要一个有效的表达式,你当然可以拥有一个涉及不完整类型的有效表达式。然而,你的问题是
template<class U>
auto check(U const&) -> typename U::value_type;
在foo
为U
时返回类型seq<foo>
。您不能按值返回不完整的类型,因此您最终会得到格式错误的表达式。您可以使用返回类型,例如void_<typename U::value_type>
(使用template<typename T> struct void_ {};
),您的测试似乎有效。