Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么通过CRTP访问派生类中的typedef时会出错?_C++_Crtp - Fatal编程技术网

C++ 为什么通过CRTP访问派生类中的typedef时会出错?

C++ 为什么通过CRTP访问派生类中的typedef时会出错?,c++,crtp,C++,Crtp,我很难理解为什么下面的代码不能编译--请有人解释一下好吗 如何从基类访问派生类中的typedef template<class Derived> struct Test { template<class T> typename Derived::value_type foo(T); }; struct Derived : public Test<Derived> { typedef int value_type; }; 模板 结构测

我很难理解为什么下面的代码不能编译--请有人解释一下好吗

如何从基类访问派生类中的typedef

template<class Derived>
struct Test
{
    template<class T>
    typename Derived::value_type foo(T);
};

struct Derived : public Test<Derived>
{
    typedef int value_type;
};
模板
结构测试
{
模板
typename派生::值\类型foo(T);
};
结构派生:公共测试
{
typedef int value_type;
};

在声明
派生的
时,
派生的
还不是一个完整的类型--您才刚刚开始声明它!因此,在专门化
测试中,模板参数是一个不完整的类型,因此不能引用嵌套名称,例如
派生::值\u类型
——这是循环逻辑

通过将返回类型设为单独的参数,可以取消问题的循环:

template <typename T, typename R> struct Test
{
    template <typename U> R foo(U);
};

template <typename R>
struct BasicDerived : public Test<BasicDerived, R>
{
    typedef R value_type;
};

typedef BasicDerived<int> Derived;
模板结构测试
{
模板R foo(U);
};
模板
结构基本派生:公共测试
{
类型定义R值_类型;
};
typedef基本派生;

您不能直接在基类中访问
typedef
s或模板类的成员,因为此时它不是一个完整的类型。允许这样做会导致循环行为:

template<class Derived>
struct Test
{
    typedef typename Derived::value_type foo;
};

struct Derived : public Test<Derived>
{
    typedef Test<Derived>::foo value_type;
};
模板
结构测试
{
typedef typename派生::value_type foo;
};
结构派生:公共测试
{
typedef测试::foo值_类型;
};
但是,您可以在方法中引用模板类的成员,因为它们直到稍后才会实例化:

template<class Derived>
struct Test
{
    void foo() { typename Derived::value_type bar; }
};

struct Derived : public Test<Derived>
{
    typedef int value_type;
};
模板
结构测试
{
void foo(){typename派生::值\类型栏;}
};
结构派生:公共测试
{
typedef int value_type;
};
或者,根据您尝试的内容,您可以将typedef作为附加模板参数传递:

template<typename value_type, class Derived>
struct Test
{
    template<class T>
    value_type foo(T);
};

struct Derived : public Test<int, Derived>
{
    typedef int value_type;
};
模板
结构测试
{
模板
值_类型foo(T);
};
结构派生:公共测试
{
typedef int value_type;
};

“您刚刚开始声明”。。。但是如果
foo
是一个模板,那么它不应该在类实例化之后很久才被计算吗?为什么它没有延迟开始?@Mehrdad:造成问题的不是
foo
的主体,而是它的声明,这是进行
测试所需要的。。。因此,如果我让返回类型以某种方式依赖于
T
,那么这会消失吗?那是。。。奇怪的