2015-10-18 80 views
3

我陷入了麻烦,因为我应该在模板中引用参数(老实说,我强烈怀疑它不可能实现我想要做的事)。从另一个参数引用的模板可变参数

它遵循想什么,我做的一个例子(当然,这在语法上不合法的,其目的是给知道哪些是目标):

template<class C, Ret(C::*Member)(Params...), typename Ret, typename... Params> 
class MyClass { } 

在其他方面,我想引用一个类的成员,同时指定返回值和该方法的参数。

不幸的是,我看这样做是像下面这样一个唯一的方法(当然,它确实依赖于在需要那些typenames,无论如何,它可能是一个有意义的例子):

template<typename Ret, typename... Params> 
class MyClass { 
public: 
    template<class C, Ret(C::*Member)(Params...)> 
    MyClass(C *c) { /* do something else and give sense to this class */ } 
} 

除了上面的那个,即通过引入一个模板化的构造函数来打破交错,那么存在另一种有效的方法来获得与唯一的类模板签名相同的结果?

我知道(很简单)如何实现在没有可变参数模板的情况下(作为一个例子,移动RetMember之前),但一个可变一个(Params)在模板列表和我的结束奠定不能以任何方式引用它。

+0

为什么你要显式传递所有类型,而不是使用'typename T,T t'方法,然后'decltype(&C :: member),&C :: member'? –

+0

我不想绑定到特定的成员,但只绑定到合同,因此我必须明确定义哪个模板是目标成员。按照你的方法,我将被迫在我的课堂中定义一个具有众所周知的名字和原型的成员,不是吗?此外,这是解决问题的另一种解决方案,而不是对我的问题的回应。 :-) – skypjack

+0

那么为什么你需要'成员'作为非类型的模板参数?是不是一个足够的签名?是[this](http://coliru.stacked-crooked.com/a/b0d3947a79be7738)你需要什么? –

回答

2

根据this question,一个可行的解决方案可能是依靠由默认值强制推演。

作为一个例子,下面的代码应该是有效的:

class MyClass { 
public: 
    template <class C, typename R, typename... P, R(C::*M)(P...) = &C::foo> 
    void bar(C *c) { } 
}; 

我举链接的问题的一部分(引文即是其自身的引文,我在一个循环中):

函数模板的模板参数包不应跟随其他模板参数,除非该模板参数可以从函数模板的参数类型列表中推导出来或具有缺省参数。

正因为如此,下面的代码不应该代替允许的,即使它与GCC编译:

class MyClass { 
public: 
    template <class C, typename R, typename... P, R(C::*M)(P...)> 
    void bar(C *c) { } 
}; 

好,相当棘手,不那么灵活的解决方案,并老实说,我结束了远前有一些重构,但为了清晰起见,我决定添加一个答案,并用编译的代码片断来解决问题。

+0

在你的第一个片段中,'R'和'... P'都不能被推导出来:http://melpon.org/wandbox/permlink/lUlLmimPYbyr22C6对于'... P',这意味着它是“推断“为空参数包,因此'&C :: foo'不会与'M'的类型兼容,除非'M'没有参数。 – dyp

+0

正确的调用就像'MyClass {} .bar (&w);'。在这个例子中没有办法推导出'R'或'P ...',但问题是关于参数包之后的最后一个类型,它必须是可以推论或默认的(就像在这个例子中那样)。所以,这是真的,你是对的,但这不是我正在讨论的内容。:-) – skypjack

+0

啊我明白了。我并没有从你的问题中完全理解你想要做什么。默认非类型参数的另一种方法是嵌套这是另一个模板:'template struct My {template struct Class {}; };我的 :: <&woof::foo> {}' – dyp

相关问题