单个模板类的变体模板包

时间:2015-07-05 01:44:19

标签: templates c++11 inheritance filtering variadic

有以下例子:

/* Signal Container */
template <typename Ret> class Signal;

template <typename Ret, typename... Args>
class Signal< Ret (Args...) >
{
    /* Following Implementation... */
};

/* Emitter Type */
template < template <typename Ret, typename... Args> Signal< Ret (Args...) > ... Sig>
class Emitter
{
    // using Signals = std::tuple<Sig...>;

    /* Following Implementation... */
};

/* Signals */
using Signal_A = Signal<void()>;
using Signal_B = Signal<void(int)>;
using Signal_C = Signal<void(int, float)>;

/* Desired Usage */
class MyType : public Emitter<Signal_A, Signal_B, Signal_C>
{

};

我希望能够从Emitter类型继承,该类型接受1 {0?)个或更多类型为Signal的模板参数(且仅Signal < / em>的)。 Signal是模板化类型,它的定义因传递给Emitter参数包的每种类型而有所不同。

我在MinGW上尝试了当前的方法,但是我收到了这些错误信息,而且我有点迷失了:

/* Line: template < template <typename Ret, typename... Args> Signal< Ret (Args...) > ... Sig> */
main.cpp|15|error: expected 'class' before 'Signal'|


/* Line: template < template <typename Ret, typename... Args> Signal< Ret (Args...) > ... Sig> */
main.cpp|15|error: expected '>' before '<' token|


/* Line: class MyType : public Emitter<Signal_A, Signal_B, Signal_C> */
main.cpp|29|error: wrong number of template arguments (3, should be 1)|


/* Linne: class Emitter */
main.cpp|16|error: provided for 'template<template<class Ret, class ... Args> class Signal> class Emitter'|

如果有人能澄清这一点或提供有效的解决方案,我将不胜感激。

可用的编译器:MinGW GCC 4.9.2(也是5.1.0)

3 个答案:

答案 0 :(得分:2)

您无法轻松地在C ++ 11或C ++ 14中执行所需操作。概念可能会给我们一些东西,但是现在你的模板参数必须是类型,类模板或值。在您的情况下,您需要一组信号,只能指定为:

template <typename... Sigs>
class Emitter;

在课程中,您可以使用static_assert来验证他们是Signal的全部内容:

static_assert(all_true<is_signal<Sigs>::value...>::value, "Emitter must use only Signals");

您必须为is_signal编写一个类型特征,并为all_true提供元函数。可以找到后者的一个示例here

答案 1 :(得分:1)

您不必匹配类模板ListView SectionHeader中所有内部类型的//Document document = null; PdfCopy pdfCopyProvider = null; PdfImportedPage importedPage = null; MemoryStream target = new MemoryStream(); try { int TotalPages = 0; MssCountPagesPDF(ssPDF.ssSTPDF.ssBinaryData, out TotalPages, out ssErrors); if (TotalPages == 0) throw new Exception("The PDF don't have any page!"); for (int i = 1; i <= TotalPages; i++) { PdfReader reader = new PdfReader(ssPDF.ssSTPDF.ssBinaryData, System.Text.ASCIIEncoding.ASCII.GetBytes(ssPDF.ssSTPDF.ssPDFPassword)); // Capture the correct size and orientation for the page: Document document = new Document(reader.GetPageSizeWithRotation(i)); // Initialize an instance of the PdfCopyClass with the source // document and an output file stream: pdfCopyProvider = new PdfCopy(document, target); document.Open(); // Extract the desired page number: importedPage = pdfCopyProvider.GetImportedPage(reader, i); pdfCopyProvider.AddPage(importedPage); //close the document document.Close(); reader.Close(); //Append PDF to the RecordList RCPDFRecord rcPDF = new RCPDFRecord(); rcPDF.ssSTPDF.ssBinaryData = target.ToArray(); ssPagesPDF.Append(rcPDF); } } catch (Exception exception) { ssErrors = exception.ToString(); throw new Exception("There has an unexpected exception" + " occured during the pdf creation process.", exception); } finally { target.Close(); } 。你只需说明它是一个接收参数的模板。之后,您需要在应用程序中重复达到Signal的最小数量。假设最小值是1,这是一个解决方案。

Emitter

答案 2 :(得分:0)

我将此作为答案发布,因为它确实满足了问题中的要求。即使我标记了一个正确的答案。我认为发布我的最终方法是合适的。

#include <iostream>

/* Signal Container */
template <typename Ret> class Signal;

template <typename Ret, typename... Args>
class Signal< Ret (Args...) >
{
    /* Following Implementation... */
};

namespace {
    /* Signal Type Traits */
    template < typename T >
    struct IsSignal { static constexpr bool Value = false; };

    template < typename T >
    struct IsSignal< Signal< T > > { static constexpr bool Value = true; };

    /* Signal Validation */
    template < bool V, typename... Args >
    struct AreSignals
    {
        static constexpr bool Value = V;
    };

    template < bool V, typename T, typename... Args >
    struct AreSignals< V, T, Args... >
    {
        static constexpr bool Value = AreSignals< V && IsSignal< T >::Value, Args... >::Value;
    };

}

/* Emitter Type */
template < typename... Args >
class Emitter
{
    // Block unsupported signals
    static_assert( AreSignals<true, Args...>::Value, "Unsupported signal type" );

    using Signals = std::tuple<Args...>;

    /* Following Implementation... */
};

using Signal_A = Signal<void()>;
using Signal_B = Signal<void(int)>;
using Signal_C = Signal<void(int, float)>;

class MyType : public Emitter<Signal_A, Signal_B, Signal_C>
{

};

int main(int argc, char **argv)
{
    std::cout << AreSignals<true, Signal_A, Signal_B, Signal_C>::Value << "\n"; // 1 (true)

    std::cout << AreSignals<true, Signal_A, int, Signal_B, Signal_C>::Value << "\n"; // 0 (false)

    return EXIT_SUCCESS;
}