gpt4 book ai didi

在派生模板类中使用 typedef 时,C++ 虚拟模板参数引发错误

转载 作者:行者123 更新时间:2023-11-30 03:26:54 25 4
gpt4 key购买 nike

我正在尝试修复我在使用此代码时遇到的一个奇怪错误。这是一个可以复制错误的最小示例:

test11.cpp :

namespace detail{
template <auto UInt>
class Test{
public:
typedef decltype(UInt) value_type;

Test (const value_type& x = 0);

protected:
value_type n;
};

template<auto UInt>
Test<UInt>::Test (const value_type& x) : n(x){}

// Here, void would be substitute with some enable_if stuff
template <auto UInt, typename = void>
class TestChild : public Test<UInt>{
public:
typedef typename Test<UInt>::value_type value_type;

TestChild (const value_type& x = 0);
value_type foo() const;
};

template<auto UInt>
TestChild<UInt>::TestChild (const value_type& x) : Test<UInt>(x){}

template<auto UInt>
value_type TestChild<UInt>::foo(){
value_type ret=42;
return ret;
}
}

int main(){}

我在 Ubuntu 16.04 LTS 中使用 GCC 7.2.0 和 Clang 5.0.0 编译了它。您可以看到这两个演示链接:

gcc 中的错误信息是这样的:

test11.cpp:27:38: error: ‘value_type’ does not name a type
TestChild<UInt>::TestChild (const value_type& x) : Test<UInt>(x){}
^~~~~~~~~~
test11.cpp:27:51: error: invalid use of incomplete type ‘class detail::TestChild<UInt>’
TestChild<UInt>::TestChild (const value_type& x) : Test<UInt>(x){}
^
test11.cpp:18:10: note: declaration of ‘class detail::TestChild<UInt>’
class TestChild : public Test<UInt>{
^~~~~~~~~
test11.cpp:30:4: error: ‘value_type’ does not name a type
value_type TestChild<UInt>::foo(){
^~~~~~~~~~

此外,对我来说真正奇怪的是,如果我在类 TestChild 的模板中省略虚拟参数(我的意思是, template<auto UInt> 而不是 template<auto UInt, typename = void> ),我仍然得到一个(更短的)错误,看起来像这样:

test11.cpp:30:4: error: ‘value_type’ does not name a type
value_type TestChild<UInt>::foo(){
^~~~~~~~~~

您可以查看 GCC 7.2.0 的演示 here .

看起来主要的错误是,如果我在类外定义函数,typedef typename Test<UInt>::value_type value_type;并没有真正被检测到(我不知道我是否解释清楚了)。

如果我在类中定义函数时也会发生这种情况,这对我来说是有意义的,但事实并非如此,因为在最后一种情况下一切都编译得很好(如果你想,你可以在 demo 中看到它).

总而言之,我的主要问题是我想编译这个程序,但要记住我必须将声明与定义分开。所以我展示的最后一个演示(所有内容都在类中定义)是我想要实现的,但是模块化。

我希望有人能帮助我并解释这段代码是怎么回事。

最佳答案

您应该(至少)进行三处更改。

首先:为 TestChild 添加第二个(默认)模板值.

所以

//................vvvvvvvvvvvv
template<auto UInt, typename V>
TestChild<UInt, V>::TestChild (const value_type& x) : Test<UInt>(x){}
//............^^^

对于foo()也是一样的方法

第二:记住foo()const

所以

template <auto UInt, typename V>
value_type TestChild<UInt, V>::foo() const {
value_type ret=42; // ...........^^^^^
return ret;
}

第三:foo() 的返回类型显式类

所以 typename TestChild<UInt, V>::value_type而不是 value_type

template <auto UInt, typename V>
typename TestChild<UInt, V>::value_type TestChild<UInt, V>::foo() const {
value_type ret=42;
return ret;
}

或者,如果您愿意,可以使用 auto ... ->返回类型语法

template<auto UInt, typename V>
auto TestChild<UInt, V>::foo() const -> value_type {
value_type ret=42;
return ret;
}

或简单地 auto (而且在方法的声明中)

auto foo() const;

// ...

template<auto UInt, typename V>
auto TestChild<UInt, V>::foo() const {
value_type ret=42;
return ret;
}

关于在派生模板类中使用 typedef 时,C++ 虚拟模板参数引发错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47851916/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com