gpt4 book ai didi

C++ 在继承构造函数中使用带有类型名的声明

转载 作者:IT老高 更新时间:2023-10-28 23:02:43 26 4
gpt4 key购买 nike

阅读时this question ,我发现了一个奇怪的地方:

template <typename T>
class Subclass : public Baseclass<T>
{
public:
using typename Baseclass<T>::Baseclass;
// ^^^^^^^^
};

自从 typename , Baseclass<T>::Baseclass应该是 injected class name ,不是构造函数。据我所知,和这个是一样的情况:

template <typename T>
class Base
{
public:
typedef short some_type;
};

template <typename T>
class Sub : public Base<T>
{
public:
using typename Base<T>::some_type;
};

为了确保,我写了一个测试代码。

#include <iostream>

template <typename T>
class Base
{
public:
Base() { std::cout << "A::A()\n"; }
Base(int) { std::cout << "A::A(int)\n"; }
Base(const char *) { std::cout << "A::A(const char *)\n"; }
};

template <typename T>
class Sub : public Base<T>
{
using typename Base<T>::Base;
};

int main()
{
Sub<char> s1;
Sub<char> s2(3);
Sub<char> s3("asdf");
}

但是,它在 gcc 4.8.3 上运行。

$ g++ -std=c++1y -Wall -Wextra -Werror -pedantic test.cpp -o test && ./test
A::A()
A::A(int)
A::A(const char *)

它也可以在没有 typename 的情况下运行.

$ cat test.cpp
...
using Base<T>::Base;
...

$ g++ -std=c++1y -Wall -Wextra -Werror -pedantic test.cpp -o test && ./test
A::A()
A::A(int)
A::A(const char *)

为什么我会得到这些结果?我错过了什么?

最佳答案

标准对此非常清楚([namespace.udecl]/1)

using-declaration:

using typename_opt nested-name-specifier unqualified-id ;

typename因此,关键字是 using 声明的 可选 部分,即使对于非类型的 using 声明也可能出现。因此,以下代码应符合标准:

template < typename T > class Base {
protected:
typedef T Ttype;
Ttype member;

public:
Base() {
std::cout << "A::A()\n";
}
Base(int) {
std::cout << "A::A(int)\n";
}
Base(const char *) {
std::cout << "A::A(const char *)\n";
}

protected:
void memfunc(void) {
std::cout << "A::memfunc(void)\n";
}
};

template< typename T >
struct SubNoTypename : protected Base< T > {
using Base< T >::Base;
using Base< T >::member;
using Base< T >::memfunc;
using Base< T >::Ttype; // n.b. no error in clang++
};

template< typename T >
struct SubTypename : protected Base< T > {
using typename Base< T >::Base; // error in clang++
using typename Base< T >::member; // error in clang++
using typename Base< T >::memfunc; // error in clang++
using typename Base< T >::Ttype;
};

两者SubNoTypenameSubTypename被 gcc 认定为符合标准。另一方面,clang++ 在 SubTypename 中提示。关于错位 typename关键字。然而,这甚至不一致,因为它应该提示缺少 typename。在 using Base< T >::Ttype; .这显然是一个 clang 错误。


编辑typename如果基类不是模板类,则也允许使用关键字,通常您不会期望此关键字有效:

class BaseNoTemplate {
protected:
typedef T Ttype;
Ttype member;

public:
BaseNoTemplate() {
std::cout << "A::A()\n";
}
BaseNoTemplate(const char *) {
std::cout << "A::A(const char *)\n";
}

void memfunc(void) {
std::cout << "A::memfunc(void)\n";
}
};

struct SubNoTemplateNoTypename : protected BaseNoTemplate {
using BaseNoTemplate::BaseNoTemplate;
using BaseNoTemplate::member;
using BaseNoTemplate::memfunc;
using BaseNoTemplate::Ttype;
};

struct SubNoTemplateTypename : protected BaseNoTemplate {
using typename BaseNoTemplate::BaseNoTemplate; // error in clang++
using typename BaseNoTemplate::member; // error in clang++
using typename BaseNoTemplate::memfunc; // error in clang++
using typename BaseNoTemplate::Ttype; // n.b. no error in clang++
};

关于C++ 在继承构造函数中使用带有类型名的声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25944000/

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