【问题标题】:Different template signatures不同的模板签名
【发布时间】:2022-01-19 22:37:30
【问题描述】:

我正在尝试学习模板上的可变参数。我的自我练习是用静态成员制作一个 NN。这个想法是在没有堆的微控制器上运行它。为此,我想使用模板来定义层之间的笛卡尔积。

weights<T,2,3,4>::type 将转化为 tuple<array<T,6>, array<T,12>>

#include<iostream>
#include <array>

template<typename T, int left, typename... U>
struct weights {
    typedef std::tuple<U...> type;
};

template<typename T, int left, int right, int... other, typename... U>
struct weights {
    typedef weights<T, right, other..., std::array<T, left*right>, U...>::type type;
};

int main() {
    weights<int, 2, 3, 4>::type o;
    return 0;
}

但是编译器似乎看到的是第一个模板参数而不是第二个。

这是我收到的消息:

weights.cpp:10:8: error: redeclared with 5 template parameters
   10 | struct weights {
      |        ^~~~~~~
weights.cpp:5:8: note: previous declaration ‘template<class T, int left, class ... U> struct weights’ used 3 template parameters
    5 | struct weights {
      |        ^~~~~~~
weights.cpp: In function ‘int main()’:
weights.cpp:15:25: error: type/value mismatch at argument 3 in template parameter list for ‘template<class T, int left, class ... U> struct weights’
   15 |     weights<int, 2, 3, 4>::type o;
      |                         ^
weights.cpp:15:25: note:   expected a type, got ‘3’
weights.cpp:15:25: error: type/value mismatch at argument 3 in template parameter list for ‘template<class T, int left, class ... U> struct weights’
weights.cpp:15:25: note:   expected a type, got ‘4’
weights.cpp:15:33: error: expected initializer before ‘o’
   15 |     weights<int, 2, 3, 4>::type o;
      |                                 ^

如何让编译器看到不同的签名?

【问题讨论】:

  • 什么是test?不相关:您应该 #include &lt;tuple&gt;int... other, typename... U 看起来像您将遇到的下一个问题(两个参数包)。我可以看到left * right 变成了6,但是 12 是从哪里来的?
  • 那是非法的......我们可以对类模板进行特化或部分特化......但是你的看起来完全是“重载”。

标签: c++ templates variadic


【解决方案1】:

不确定是否是最好的方法,但这就是我解决它的方法:

#include <iostream>
#include <array>
#include <tuple>

namespace weights_ns {
    template <bool last>
    struct weights;

    template <>
    struct weights<true> {
        template<typename T, typename... U>
        struct supertype_0 {
            template<int left> //, int right, int... other>
            struct supertype_1 :
                public std::tuple<U...>
            {};
        };
    };

    template <>
    struct weights<false> {
        template<typename T, typename... U>
        struct supertype_0 {
            template<int left, int right, int... other>
            struct supertype_1 :
                public weights_ns::weights<(sizeof...(other)==0)>::template supertype_0<T, std::array<T, left*right>, U...>::template supertype_1<right, other...>
            {};
        };
    };

};

int main() {
    std::cout << "size: " << sizeof(weights_ns::template weights<false>::template supertype_0<char>::template supertype_1<2,3,5>) << std::endl;
}

【讨论】:

    【解决方案2】:

    我不确定如何改进您的答案,但您可以稍微清理一下使用界面

    #include <iostream>
    #include <array>
    #include <tuple>
    
    namespace weights_ns {
        template <bool last>
        struct container;
    
        template <>
        struct container<true> {
            template<typename T, typename... U>
            struct supertype_0 {
                template<int left>
                struct supertype_1 :
                    public std::tuple<U...>
                {};
            };
        };
    
        template <>
        struct container<false> {
            template<typename T, typename... U>
            struct supertype_0 {
                template<int left, int right, int... other>
                struct supertype_1 :
                    public weights_ns::container<(sizeof...(other)==0)>::template supertype_0<T, std::array<T, left*right>, U...>::template supertype_1<right, other...>
                {};
            };
        };
    
        template<typename T, T... Layers>
        struct weights: public weights_ns::container<(sizeof...(Layers) < 2)>::template supertype_0<T>::template supertype_1<Layers...>
        {};
    };
    
    int main() {
        weights_ns::weights<int, 2, 3, 5> t;
        std::cout << "size: " << sizeof(t) << std::endl;
        return 0;
    }
    

    【讨论】:

    • 有人指出顺序颠倒了。代码应该是 supertype_0>::
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    相关资源
    最近更新 更多