为什么这个带有可变参数模板参数的构造函数不匹配?

发布于 2024-12-11 17:31:11 字数 2133 浏览 0 评论 0 原文

我已经实现了一个处理管道,但我想像这样改进它:

#include <iostream>

// buffers
struct src{}; struct b1{}; struct snk{};
// filters
struct f1
{
    f1( const src &, b1 & ) { std::cout << "f1( src, b1 )" << std::endl; }
};
struct f2
{
    f2( const b1 &, snk & ) { std::cout << "f2( b1, snk )" << std::endl; }
};
// the pipeline
template< typename... Filters >
struct pipeline
{
    template< typename LastB >
    pipeline( const LastB & )
    {}
};
template < typename T1, typename... T >
struct pipeline< T1, T... > : pipeline< T... >
{
    template< typename... Buffs, typename Bin, typename Bout >
    pipeline( Buffs &... buffs, Bin & bin, Bout & bout ) :
        pipeline< T... >( buffs..., bin ),
        filter( bin, bout )
    {
    }

    T1 filter;
};

int main()
{
    src ba; b1  bb; snk bc;

    pipeline< f1 > p1( ba, bb );
    pipeline< f1, f2 > p2( ba, bb, bc ); // the problem is in this line!
}

不幸的是,上面的示例产生了下一个错误:

sda_variadic.cpp: In function 'int main()':
sda_variadic.cpp:40:39: error: no matching function for call to 'pipeline<f1, f2>::pipeline(src&, b1&, snk&)'
sda_variadic.cpp:40:39: note: candidates are:
sda_variadic.cpp:26:5: note: template<class ... Buffs, class Bin, class Bout> pipeline<T1, T ...>::pipeline(Buffs& ..., Bin&, Bout&)
sda_variadic.cpp:23:8: note: constexpr pipeline<f1, f2>::pipeline(const pipeline<f1, f2>&)
sda_variadic.cpp:23:8: note:   candidate expects 1 argument, 3 provided
sda_variadic.cpp:23:8: note: constexpr pipeline<f1, f2>::pipeline(pipeline<f1, f2>&&)
sda_variadic.cpp:23:8: note:   candidate expects 1 argument, 3 provided

这个错误的原因是什么?
如何修复它?

只是一个小解释。我希望上面的示例将首先创建非专用的 pipeline( snk ) 对象,然后创建专用的 pipelinepipeline 对象。 f1 >(b1,snk),然后是专门的对象pipeline f1, f2 >(src,b1,snk)
顺便说一句,请注意,上面的示例适用于 1 个过滤器 (pipeline)。

I have a processing pipeline implemented, but I would like to improve it like this :

#include <iostream>

// buffers
struct src{}; struct b1{}; struct snk{};
// filters
struct f1
{
    f1( const src &, b1 & ) { std::cout << "f1( src, b1 )" << std::endl; }
};
struct f2
{
    f2( const b1 &, snk & ) { std::cout << "f2( b1, snk )" << std::endl; }
};
// the pipeline
template< typename... Filters >
struct pipeline
{
    template< typename LastB >
    pipeline( const LastB & )
    {}
};
template < typename T1, typename... T >
struct pipeline< T1, T... > : pipeline< T... >
{
    template< typename... Buffs, typename Bin, typename Bout >
    pipeline( Buffs &... buffs, Bin & bin, Bout & bout ) :
        pipeline< T... >( buffs..., bin ),
        filter( bin, bout )
    {
    }

    T1 filter;
};

int main()
{
    src ba; b1  bb; snk bc;

    pipeline< f1 > p1( ba, bb );
    pipeline< f1, f2 > p2( ba, bb, bc ); // the problem is in this line!
}

Unfortunately, the example above produces next errors :

sda_variadic.cpp: In function 'int main()':
sda_variadic.cpp:40:39: error: no matching function for call to 'pipeline<f1, f2>::pipeline(src&, b1&, snk&)'
sda_variadic.cpp:40:39: note: candidates are:
sda_variadic.cpp:26:5: note: template<class ... Buffs, class Bin, class Bout> pipeline<T1, T ...>::pipeline(Buffs& ..., Bin&, Bout&)
sda_variadic.cpp:23:8: note: constexpr pipeline<f1, f2>::pipeline(const pipeline<f1, f2>&)
sda_variadic.cpp:23:8: note:   candidate expects 1 argument, 3 provided
sda_variadic.cpp:23:8: note: constexpr pipeline<f1, f2>::pipeline(pipeline<f1, f2>&&)
sda_variadic.cpp:23:8: note:   candidate expects 1 argument, 3 provided

What is the reason for this error?
How to fix it?

Just a small explanation. I expect that the example above will first create an object of the unspecialized pipeline<>( snk ), then the specialized object pipeline< f1 >(b1,snk), and then the specialized object pipeline< f1, f2 >(src,b1,snk).
btw take a note that the above example works for 1 filter (pipeline< f1).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

玻璃人 2024-12-18 17:31:11
template< typename... Buffs, typename Bin, typename Bout >
pipeline( Buffs &... buffs, Bin & bin, Bout & bout ) :
    pipeline< T... >( buffs..., bin ),
    filter( bin, bout )
{
}

由于函数参数包(Buffs)不在最后位置,因此无法推导。从 14.8.2.1 从函数调用推导模板参数 [temp.deduct.call] 第 1 段:

  1. [...] 对于未出现在参数声明列表末尾的函数参数包,参数包的类型是非推导上下文。 [...]

由于您无法显式地将模板参数传递给构造函数,因此根本无法调用它(但这对您的问题并不重要)。

我建议使用 std::tuple 来操作可变参数,这样您就可以像这样调用构造函数: pipeline(std::forward_as_tuple(b0, b1, b2), in, out) 并且一个空元组将被传递到最后一个阶段。

template< typename... Buffs, typename Bin, typename Bout >
pipeline( Buffs &... buffs, Bin & bin, Bout & bout ) :
    pipeline< T... >( buffs..., bin ),
    filter( bin, bout )
{
}

Since the function parameter pack (Buffs) is not in the last position, it cannot be deduced. From 14.8.2.1 Deducing template arguments from a function call [temp.deduct.call] paragraph 1:

  1. [...] For a function parameter pack that does not occur at the end of the parameter-declaration-list, the type of the parameter pack is a non-deduced context. [...]

Since you can't explicitly pass template parameters to a constructor, it can't be called at all (not that it matters for your problem though).

I'd recommend using std::tuple to manipulate the variadic arguments, such that you call the constructor like so: pipeline(std::forward_as_tuple(b0, b1, b2), in, out) and an empty tuple would be passed to the last stage.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文