C++ 从作为模板参数传递的常量类型继承

C++ 从作为模板参数传递的常量类型继承,c++,c++11,c++14,language-lawyer,C++,C++11,C++14,Language Lawyer,以下代码无效: struct base { }; struct inherit : const base { }; 不能从常量继承类型 当涉及模板时,情况是否会改变?换句话说,此代码是否有效: struct base { }; template<typename T> struct inherit : T { using T::T; }; int main() { inherit<base const>{}; } struct base{ };

以下代码无效:

struct base {
};

struct inherit : const base {
};
不能从
常量继承
类型

当涉及模板时,情况是否会改变?换句话说,此代码是否有效:

struct base {
};

template<typename T>
struct inherit : T {
    using T::T;
};

int main() {
    inherit<base const>{};
}
struct base{
};
模板
结构继承:T{
使用T::T;
};
int main(){
继承{};
}
gcc表示一切正常,但clang报道

<source>:6:2: error: 'const base' is not a direct base of 'inherit<const base>', cannot inherit constructors

        using T::T;

        ^        ~

<source>:10:2: note: in instantiation of template class 'inherit<const base>' requested here

        inherit<base const>{};

        ^

1 error generated.

Compiler returned: 1
:6:2:错误:“const base”不是“inherit”的直接基,无法继承构造函数
使用T::T;
^        ~
:10:2:注意:在此处请求的模板类“继承”的实例化中
继承{};
^
生成1个错误。
返回的编译器:1
为了让叮当高兴,我需要做如下事情:

template<typename T>
struct inherit : T {
    using U = std::remove_const_t<T>;
    using U::U;
};
模板
结构继承:T{
使用U=std::删除常数;
使用U::U;
};
哪个版本是正确的?或者它们都不正确,我需要继承自
std::remove\u const\t

感谢我们有:

根据:

标识符不在省略号后面的类型参数将其标识符定义为typedef名称(如果使用
class
typename
声明)。。。在模板声明的范围内

因此,它的工作原理就像
typedef

然后:

如果在需要类名的地方使用了命名cv限定类类型的typedef名称,则cv限定符将被忽略


因此GCC是正确的,
const
在从
T
继承时应该被剥离,因为需要一个类名,以及在继承构造函数声明中。

在确定模板参数的类型时,模板参数上的顶级cv限定符不是被忽略了吗?@Justin@rustyx非模板表单格式错误,因为语法不允许在该位置使用cv限定符。模板格式很好,clang的诊断消息完全是胡说八道。您不需要模板来复制它:
使用cbase=const base
和继承自
cbase
就足够了;我将使用T::T添加
,因为[class.name]/5已经被引用,[class.qual]/2.2指定,由于标识符
T
重复,因此该名称“被视为命名构造函数”,而不在类中查找名称
T