【问题标题】:c++ template with typedef multiple argument?带有typedef多个参数的c ++模板?
【发布时间】:2017-03-15 17:34:35
【问题描述】:

我有一个带有 5 个模板参数的模板类,看起来与此类似。

SomeClass.h

template < typename A, typename B, typename C, typename D >
class SomeClass
{
private:
A a_obj;
B b_obj;
C c_obj;
D d_obj;
public:
void someoperationA();
void someoperationB();
void someoperationC();
};

SomeClass.cpp

template < typename A, typename B, typename C, typename D >
SomeClass<A, B, C, D>::someoperationA()
{
 A::someStaticMethods();
}

template < typename A, typename B, typename C, typename D >
SomeClass<A, B, C, D>::someoperationB()
{}

template < typename A, typename B, typename C, typename D >
SomeClass<A, B, C, D>::someoperationC()
{}

考虑一下我的模板参数应该被赋予一些好名字的情况,比如

SomeClass.cpp

template < 
typename ABIGCLASSNAME, 
typename BBIGCLASSNAME, 
typename CBIGCLASSNAME, 
typename DBIGCLASSNAME 
>
SomeClass<ABIGCLASSNAME, 
BBIGCLASSNAME, 
CBIGCLASSNAME, 
DBIGCLASSNAME>::someoperationA()
{
ABIGCLASSNAME::someStaticMethods();
}

它肯定开始看起来很丑:(

那么有没有可能以任何方式 typedef 模板参数,以便它可读...类似的东西

typedef template < typename ABIGCLASSNAME, typename BBIGCLASSNAME, typename CBIGCLASSNAME, typename DBIGCLASSNAME > TEMP_WITH_PARAMS

和类类似的东西除了使用#define

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    考虑创建一个包装器struct,其中包含您所需的所有参数,并将SomeClass 模板化:

    template < typename A, typename B, typename C, typename D >
    struct Settings
    {
        using AType = A;
        using BType = B;
        using CType = C;
        using DType = D;
    };
    

    template < typename TSettings >
    class SomeClass { /* ... */ } 
    

    template < typename TSettings >
    SomeClass<TSettings>::someoperationB() { /* ... */ }
    

    优点:

    • 样板文件少得多。

    • 如果您决定添加新模板参数或更改现有模板参数,您只需更改Settings

    使用 type trait 保留您的原始界面也很简单:

    template < typename A, typename B, typename C, typename D >
    using SomeClass = SomeClassImpl<Settings<A, B, C, D>>;
    

    考虑使用可变类型特征以避免重复A, B, C, D

    template < typename... Ts >
    using SomeClass = SomeClassImpl<Settings<Ts...>>;
    

    【讨论】:

    • 我应该学会不要给出如此明确的“不,没有”的答案。 :)。我喜欢你的解决方案。
    • +1 或者,可能只需在内部使用 template &lt;typename ...Pack&gt; SomeClassImpl {...};using LongNameA = typename std::tuple_element&lt;0, std::tuple&lt;Pack...&gt;&gt;::type; 即可。
    【解决方案2】:

    不,没有

    请注意,您不能在源 (.cpp) 文件中包含模板定义。见Why can templates only be implemented in the header file?

    有一个提议要定义一个类命名空间,其中所有定义都被认为是该类的成员,这本来可以解决您的问题,但它并没有引起太大的关注。

    所以要么编写所有模板参数(但在标题中),要么在类中定义它们。我个人更喜欢在类中定义方法,因为无论如何我都必须在标题中定义 then,我认为在类之外定义它们与编写两次代码的麻烦相比没有太大优势。

    您可以做的另一个技巧是使用非常短的模板参数名称并在类中使用全名别名。例如:

    template <class F> struct S {
       using Function = F;
    };
    

    【讨论】:

      【解决方案3】:

      描述性模板参数的名称很好。但是一旦你最初指定了它们,你就不必拖动它们了。有两件事可以帮助您:

      1. using 在类中有一个短别名。
      2. 您不必为类外定义的模板参数使用相同的名称。

        #include <iostream>
        template <typename SomeLongAndUglyName>
        class ImPretty {
          public: 
            using SimplyUgly = SomeLongAndUglyName;
        
          void foo();
        };
        
        template <typename Ugly>
        void ImPretty<Ugly>::foo() {
          std::cout << "pretty" << std::endl;
        }
        

      【讨论】:

        猜你喜欢
        • 2013-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-04
        • 1970-01-01
        相关资源
        最近更新 更多