【问题标题】:how to solve unqualified name lookup problem如何解决不合格名称查找问题
【发布时间】:2019-07-15 16:53:32
【问题描述】:

我有以下简化程序:

class Base { };

template < typename T >
class X: public T
{
    public:
        using TOP = T;
};

// with dependent template parm    
template < typename T >
class Y: public X< T >
{
    // I have to write down the full name of the base class
    using X<T>::TOP::operator =;
};

// without depending template parameter
template < typename T >
class Y: public X< Base >
{
    // I simply can use the defined type from the base class
    using TOP::operator =;
};


int main()
{
    Y< Base > y ;
}

现在的问题是,是否有任何方法可以简化完整的重复 基类类型。我的原始代码是这样的:

template < typename VAR_TYPE >
class VarObserved: public ConstructAll2<
                   UsingHelperV_None,
                   UsingHelper_None,
                   CONTAINERL< AssignConst >,
                   CONTAINERL< Print >,
                   CONTAINERL< DataStore >,
                   CONTAINERL< Distribute_ >,
                   CONTAINERL< EndForward >,
                   CONTAINERSP< DataStoreBase, VAR_TYPE >
                   >
{
    public:
        using SELF = ConstructAll2<
            UsingHelperV_None,
            UsingHelper_None,
            CONTAINERL< AssignConst >,
            CONTAINERL< Print >,
            CONTAINERL< DataStore >,
            CONTAINERL< Distribute_ >, 
            CONTAINERL< EndForward     >,
            CONTAINERSP< DataStoreBase, VAR_TYPE >   // see text 1)
                >;

        VarObserved( const VAR_TYPE& var ): SELF{{ var }}{}
        using SELF::AssignConst::operator=;
};

如您所见,所有模板参数的完全重复并​​不是很“好”。有机会解决吗?

如果上面的代码没有依赖模板参数(将单行1.))从上面的示例中改为:

CONTAINERSP< DataStoreBase, int>

这个类变得非常简单并且更容易维护:

...
VarObserved( const VAR_TYPE& var ): ConstructAll2{{ var }}{}
using AssignConst::operator=;
....

作为对潜在问题的参考,我已经发现了那个问题

"not declared in this scope" error with templates and inheritance

但不知道如何简化我的代码。

【问题讨论】:

  • 更正了我的答案(贾斯汀观察到,不需要专业化);对不起。

标签: c++ templates unqualified-name


【解决方案1】:

现在的问题是,是否有任何方法可以简化基类类型的完全重复。

要查找在依赖基类中声明的名称TOP,您可以编写Y::TOP 而不是X&lt;T&gt;::TOP,尽管这可能会使读者感到困惑,您可能应该评论一下为什么要这样做。

之所以可行,是因为它不再是不合格的查找。请注意,您不需要在此处写出模板参数(Y 是注入的类名,与Y&lt;T&gt; 含义相同)。

【讨论】:

  • 哇,这让它变得非常简单!简单地复制没有模板参数的类名很好!但是为构造函数提供了一个有趣的语法:VarObserved( const VAR_TYPE&amp; var ): VarObserved::ConstructAll2{{ var }}{}
【解决方案2】:

也许使用具有默认值的新模板参数(根据 Justin 的观察进行了更正)?

template <typename VAR_TYPE, typename CA2 = ConstructAll2<
                   UsingHelperV_None,
                   UsingHelper_None,
                   CONTAINERL< AssignConst >,
                   CONTAINERL< Print >,
                   CONTAINERL< DataStore >,
                   CONTAINERL< Distribute_ >,
                   CONTAINERL< EndForward >,
                   CONTAINERSP< DataStoreBase, VAR_TYPE >>>
class VarObserved : public CA2
 {
    public:
        using SELF = CA2;

        VarObserved( const VAR_TYPE& var ): SELF{{ var }}{}
        using SELF::AssignConst::operator=;
 };

【讨论】:

  • 这种方法的一个缺点是ConstructAll2&lt; ... &gt; 以符号名称结尾。
  • @Justin - “为什么是模板专业化?” - 因为我混淆了自己混合两种不同的想法。更正;谢谢。
  • 我以为我之前已经尝试过,编译器并不幸运……如果可行,那将是最好的方法,因为它不需要拆分定义。明天我会检查我的“怪物”模板 :-) 谢谢!
【解决方案3】:

除了来自 max66 的想法,我还找到了以下解决方案,不是基于专业化而是基于模板模板参数:

template < typename VAR_TYPE >
using VarObserved_Parms = ConstructAll2<
    UsingHelperV_None,
    UsingHelper_None,
    CONTAINERL< AssignConst >,
    CONTAINERL< Print >,
    CONTAINERL< DataStore >,
    CONTAINERL< Distribute_ >,
    CONTAINERL< EndForward >,
    CONTAINERSP< DataStoreBase, VAR_TYPE >
    >;

template < typename VAR_TYPE, template <typename> class COMPONENTS >
class VarObserved2: public COMPONENTS< VAR_TYPE >
{
    using SELF = COMPONENTS< VAR_TYPE >;

    VarObserved2( const VAR_TYPE& var ): SELF{{ var }}{}
    using SELF::AssignConst::operator=;
};

在我从布赖恩那里得到这个想法后,一切都崩溃了:

template < typename VAR_TYPE >
class VarObserved: public ConstructAll2<
                   UsingHelperV_None,
                   UsingHelper_None,
                   CONTAINERL< AssignConst >,
                   CONTAINERL< Print >,
                   CONTAINERL< DataStore >,
                   CONTAINERL< Distribute_ >,
                   CONTAINERL< EndForward >,
                   CONTAINERSP< DataStoreBase, VAR_TYPE >
                   >
{
    public:
        VarObserved( const VAR_TYPE& var ): VarObserved::ConstructAll2{{ var }}{}
                                            ^^^^^^^^^^^^^ never saw that before, interesting syntax ;)
        using VarObserved::AssignConst::operator=;
};

【讨论】:

  • 为什么需要模板模板参数?为什么不跳过它直接使用VarObserved_Params
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多