gpt4 book ai didi

c++ - 传递对 Variadic 模板的引用

转载 作者:可可西里 更新时间:2023-11-01 16:18:27 25 4
gpt4 key购买 nike

我正在开发一个事件库,但我遇到了 Variadic 模板的问题。

一切都很好,除了我不能将引用作为参数传递...

这是一个非常简化的示例,用于揭示我的问题。

struct DelayedSignal 
{
~DelayedSignal ()
{ std::cout << "~DelayedSignal CLOSE" << std::endl; }

template<class C, class... Args>
DelayedSignal ( void(C::*func)(Args...), C& obj )
{ std::cout << "DelayedSignal INIT - 03 - pointer to method & pointer to class instance (Arg num: " << sizeof...(Args) << ")" << std::endl; }

template<class C, class... Args>
DelayedSignal ( void(C::*func)(Args...), C& obj, Args... args )
{
std::cout << "DelayedSignal INIT - 04 - pointer to method & pointer to class instance & arguments (Arg num: " << sizeof...(Args) << ")" << std::endl;
}
};

template<class... ArgsBis>
struct DelayedSignal_DebugHelper
{
~DelayedSignal_DebugHelper ()
{ std::cout << "~DelayedSignal_DebugHelper CLOSE" << std::endl; }

template<class C, class... Args>
DelayedSignal_DebugHelper ( void(C::*func)(Args...), C& obj )
{ std::cout << "DelayedSignal_DebugHelper INIT - 03 - pointer to method & pointer to class instance (Arg num: " << sizeof...(Args) << ")" << std::endl; }

template<class C, class... Args>
DelayedSignal_DebugHelper ( void(C::*func)(Args...), C& obj, ArgsBis... args ) // Need to use ArgsBis instead of Args to make it work
{
std::cout << "DelayedSignal_DebugHelper INIT - 04 - pointer to method & pointer to class instance & arguments (Arg num: " << sizeof...(Args) << ")" << std::endl;
}
};


template < class Tr, class... Args >
struct Signal
{
void fire ( Args... args ) { std::cout << "Signal::fire::" << sizeof...(Args) << std::endl; }
};

struct Klass {};


int main()
{
std::string str1("Blop"); // Will be used as reference
Klass k; // Will be used as reference

Signal<void, Klass&> signal_01;
Signal<void, std::string&> signal_02;

std::cout << "====== DelayedSignal :: needed for production purpose ===============" << std::endl;

// OK
DelayedSignal test01(&Signal<void, std::string&>::fire, signal_02);
// HERE IS THE PROBLEM
//DelayedSignal test02(&Signal<void, std::string&>::fire, signal_02, str1);

// OK
DelayedSignal test03(&Signal<void, Klass&>::fire, signal_01);
// HERE IS THE PROBLEM
//DelayedSignal test04(&Signal<void, Klass&>::fire, signal_01, k);

std::cout << "====== DelayedSignal_DebugHelper :: used only for debug purpose ======" << std::endl;

// OK
DelayedSignal_DebugHelper<std::string&> test05(&Signal<void, std::string&>::fire, signal_02);
// OK
DelayedSignal_DebugHelper<std::string&> test06(&Signal<void, std::string&>::fire, signal_02, str1);

// OK
DelayedSignal_DebugHelper<Klass&> test07(&Signal<void, Klass&>::fire, signal_01);
// OK
DelayedSignal_DebugHelper<Klass&> test08(&Signal<void, Klass&>::fire, signal_01, k);

return 1;
}

当我将所有 DelayedSignal 实例注册到单个 std::list 实例中时,我想避免在类本身上使用模板,这就是我在构造函数上使用模板的原因。我也可以使用纯虚拟类作为所有 DelayedSignal 的基础,并将指向虚拟类的指针注册到 std::list 中,但我认为最好尽量减少虚拟方法的使用,我真的对这个问题很感兴趣......

如您在此示例中所见,test02 和 test04 在被激活时会返回错误。DelayedSignal_DebugHelper 几乎与 DelayedSignal 相同,除了它在最后一个构造函数上使用 ArgsBis(类模板参数)而不是 Args 模板(方法模板参数),否则它不起作用(与 DelayedSignal 一样)。 Args 在 void(C::*func)(Args...) 上被接受但不是 ArgsBis... args尽管它们在同一个构造函数声明中。

据我所知,没有引用(例如 DelayedSignal test04(&Signal<void, Klass>::fire, signal_01, k);)或有多个参数(或没有)只要没有引用就没有问题。

有没有办法解决这个问题?

谢谢。

最佳答案

我正在使用 clang,它给出了一个非常棒的错误消息:

test.cpp:59:19: error: no matching constructor for initialization of 'DelayedSignal'
DelayedSignal test02(&Signal<void, std::string&>::fire, signal_02, str1);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:9:5: note: candidate constructor template not viable: requires 2 arguments, but 3 were provided
DelayedSignal ( void(C::*func)(Args...), C& obj )
^
test.cpp:13:5: note: candidate template ignored: deduced conflicting types for parameter 'Args'
(<std::__1::basic_string<char> &> vs. <std::__1::basic_string<char>>)
DelayedSignal ( void(C::*func)(Args...), C& obj, Args... args )
^

编译器为 Args 推断出冲突的类型:

  1. std::string&
  2. std::string

我相信解决此问题的最佳方法正是您使用 DelayedSignal_DebugHelper 完成此操作的方式。

关于c++ - 传递对 Variadic 模板的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5534585/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com