gpt4 book ai didi

c++ - 基类之后的专用 type_traits = 未定义的行为?

转载 作者:行者123 更新时间:2023-11-30 01:38:20 25 4
gpt4 key购买 nike

我想让用户控制基类的“内部类型”。此代码工作正常。

版本 1 ( demo )

//library layer
template<class Derived> class BT_trait{
public: using type=int;
};
template<class Derived> class BT{
public: using typee=typename BT_trait<Derived>::type;
public: typee f(){ return 1;}
};
//user code below
class C;
template<> class BT_trait<C>{
public: using type=std::string; //<-- user want to set "internal type"
};
class C : public BT<C> {
public: typee f(){ return "OK";}
};
int main(){
C bt;
std::cout<< bt.f();
}

如果我通过添加模板参数使其变得更复杂一点,它将不再可编译。
(如下所示)

版本 2(demo)

template<class Derived> class BT_trait{
public: using type=int;
};
template<class Derived,class Dummy> class BT{
public: using typee=typename BT_trait<Derived>::type;
public: typee f(){ return 1;}
};
//user code below
template<class T> class C;
template<class T> class BT_trait<C<T>>{
public: using type=std::string;
};
template<class T> class C : public BT<C<T>,T> {
// public: typename BT<C<T>, T>::typee f(){ return "OK";} //Version #2b
public: typee f(){ return "OK";} //Version #2a
//^ error: 'typee' does not name a type; did you mean 'wctype'?
};
int main(){
C<int> bt;
std::cout<< bt.f();
}

但是如果我使用#2b(脏)而不是#2a(简洁),上面的代码就可以正常工作。
为什么?是否有可能使 #2a 工作?

根据 Specialization of template function after point of use will break the compilation 的引述:-

Section [temp.expl.spec] 14.7.3p6 : If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.

我怀疑我的代码是未定义的行为。对吗?
我对模板特化非常陌生。

最佳答案

不,您的代码不显示 UB,甚至在编译时也不会显示。

问题是一旦C成为模板,两阶段查找规则开始在其中应用。基本上,在解析模板时查找不依赖于模板参数的名称,此时 T 的参数当然是未知的,因此编译器无法查看 BT<C<T>, T>并找到 typee在那里定义。所以它失败了。

你必须标记typee作为依赖名称(因为它确实依赖于 T )。你有几种方法:

  • 引用它时对其进行限定:

    public: typename C::typee f(){ return "OK";}

    [Live example]

  • 将其纳入您的类(class)范围(同样由 VTT's answer 建议):

    using typename BT<C<T>, T>::typee;
    public: typee f(){ return "OK";}

关于c++ - 基类之后的专用 type_traits = 未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48146177/

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