有以下例子:
/* 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)
答案 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;
}