Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 传递对可变模板的引用_C++_Templates_C++11_Variadic - Fatal编程技术网

C++ 传递对可变模板的引用

C++ 传递对可变模板的引用,c++,templates,c++11,variadic,C++,Templates,C++11,Variadic,我正在开发一个事件库,我面临可变模板的问题 除了我不能将引用作为参数传递之外,所有这些都工作得很好 下面是一个非常简单的例子,用来说明我的问题 struct DelayedSignal { ~DelayedSignal () { std::cout << "~DelayedSignal CLOSE" << std::endl; } template<class C, class... Args> DelayedSign

我正在开发一个事件库,我面临可变模板的问题

除了我不能将引用作为参数传递之外,所有这些都工作得很好

下面是一个非常简单的例子,用来说明我的问题

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;
}
struct DelayedSignal
{   
~DelayedSignal()

{std::cout我使用的是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 )
    ^
test.cpp:59:19:错误:没有用于“DelayedSignal”初始化的匹配构造函数
延迟信号测试02(和信号::火灾、信号_02、str1);
^      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:9:5:注意:候选构造函数模板不可行:需要2个参数,但提供了3个
延迟信号(无效(C::*func)(参数…,C&obj)
^
test.cpp:13:5:注意:已忽略候选模板:推断参数“Args”的冲突类型
(对)
DelayedSignal(无效(C::*func)(参数…,C&obj,参数…)
^
编译器为
Args
推断冲突类型:

  • std::string&
  • std::string

  • 我相信解决这一问题的最佳方法就是如何使用您的
    DelayedSignal\u DebugHelper

    Howard Hinnant是正确的……另一种可能是在任何地方使用引用,例如:

    #include <iostream>
    
    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 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);
    
    }
    
    #包括
    结构延迟信号
    {   
    ~DelayedSignal()
    
    {std::cout既然你已经接受了答案,这只是一个补充。 虽然我可能会忽略一些东西,
    identity
    类模板 以下内容似乎使您的代码可编译。
    例如:

    template<class T> struct identity { typedef T type; };
    
    struct DelayedSignal
    {
        ...
        template<class C, class... Args>
        DelayedSignal ( void(C::*func)(Args...), C& obj, typename identity<Args>::type... args )
        {
           ...
        }
    };
    
    模板结构标识{typedef T type;};
    结构延迟信号
    {
    ...
    模板
    
    DelayedSignal(void(C::*func)(Args…),C&obj,typename identity

    @Valke你不应该用C++0x标记这个吗?我试着编译你的解决方案,想知道为什么它在Visual Studio 2011中不起作用;在查找可变模板后,我才意识到如果搜索正确,这是一个新功能。到底是什么编译器支持这个功能?@leet:添加了标记。这个功能是h从4.3版开始,g++就一直支持这一点——有关更多信息,请参阅此链接:@Ben Voigt:我正在使用GCC 4.5。0@leetNightshade:哦,对不起,是的,我确实使用C++0x编译它。@TonyK:谢谢您添加了标记。您好,非常有趣,而且…很奇怪。我的错误消息没有那么描述性:
    main.cpp:2:74:错误:没有用于调用的匹配函数'DelayedSignal::DelayedSignal(void(Signal::*)(std::basic_string&),Signal&,std::string&)main.cpp:57:1:注:候选项为:DelayedSignal::DelayedSignal(const DelayedSignal&)
    但您对冲突类型的看法似乎是正确的。我没有太过强硬……我想我必须改变我实现延迟信号的方式。感谢您的帮助。此解决方案至少部分解决了我的问题。这两个答案都是有效的,但由于我只能选择其中一个,因此我选择了具有部分解决方案的一个N