繁体   English   中英

参数包和成员函数指针类型推导

[英]Parameter pack and member function pointer type deduction

我对clang和参数包有一点问题。

lang版本是:

Apple LLVM version 9.0.0 (clang-900.0.38)
Target: x86_64-apple-darwin16.7.0
Thread model: posix

我在以下代码段中设法重现了一个问题:

class Foo{
  public:
    int fIsOk;
    bool fIsNotOk;
    bool fTheThird;
    Foo() : fIsOk(5),fIsNotOk(false),fTheThird(true){}
    inline bool isOk() const {return fIsOk; }
    inline bool isNotOk() const {return fIsNotOk; }
    inline bool theThird() const {return fTheThird; }
    inline int is1(int yours1) const {return fIsOk+yours1; }
    inline bool is2(bool yours1,bool yours2) const {return fTheThird && yours1 && yours2; }
    inline bool getTrue() const {return true;}
};

class User{
  public:
    User() : pippo(){};
    template<typename T,class ...Args> T doIt(int i=2, T (Foo::*condition)(Args...)const = &Foo::getTrue,Args... args){
      return (pippo.*condition)(args...)+i;
    }
  private:
    Foo pippo;
};

int testParameterPack(){
  User pluto;
  std::cout<<pluto.doIt(1,&Foo::isOk)<<std::endl;
  std::cout<<pluto.doIt(2,&Foo::is1,1)<<std::endl;
  std::cout<<pluto.doIt(3,&Foo::is2,true,false)<<std::endl;
  return 0;
}

在编译时,我得到:在input_line_9:1包含的文件中:

[...]/testParameterPack.cxx:23:114: error: missing default argument on parameter 'args'
    template<typename T,class ...Args> T doIt(int i=2, T (Foo::*condition)(Args...)const = &Foo::getTrue,Args... args){
                                                                                                                 ^
[...]/testParameterPack.cxx:33:20: note: in instantiation of function template specialization 'User::doIt<int, int>' requested here
  std::cout<<pluto.doIt(2,&Foo::is1,1)<<std::endl;
                   ^
[...]/testParameterPack.cxx:23:114: error: missing default argument on parameter 'args'
    template<typename T,class ...Args> T doIt(int i=2, T (Foo::*condition)(Args...)const = &Foo::getTrue,Args... args){
                                                                                                                 ^
[...]/testParameterPack.cxx:34:20: note: in instantiation of function template specialization 'User::doIt<bool, bool, bool>' requested here
  std::cout<<pluto.doIt(3,&Foo::is2,true,false)<<std::endl;
                   ^
[...]/testParameterPack.cxx:23:114: error: missing default argument on parameter 'args'
    template<typename T,class ...Args> T doIt(int i=2, T (Foo::*condition)(Args...)const = &Foo::getTrue,Args... args){

即使对我来说,参数包也(必须)不需要默认值。 有人可以解释为什么我观察这种行为吗? 预先感谢您的帮助

gf

有趣。

我看到g ++编译了您的代码,而clang ++给出了错误。

在不知道谁是对的,但我想问题出在你不能编写如下函数

int foo (int a = 0, long b) // compilation error: no default value for b
 { return 0; }

我的意思是:当您具有参数的默认值时,以下所有参数都必须具有默认值。

所以,当你写

template <typename T, class ... Args>
T doIt (int i=2, T (Foo::*condition)(Args...)const = &Foo::getTrue,
        Args... args)
 { return (pippo.*condition)(args...)+i; }

并用一个空的可变参数列表来调用它

pluto.doIt(1,&Foo::isOk)

一切顺利,因为您创建了

bool doIt (int i=2, bool (Foo::*condition)()const = &Foo::getTrue)
 { return (pippo.*condition)()+i; }

所以所有参数都有一个默认值

但是,当您使用不空的可变参数列表调用doIt()时,例如

pluto.doIt(2,&Foo::is1,1)

您要求实现doIt()函数

int doIt (int i=2, int (Foo::*condition)(int) const = &Foo::getTrue,
          int arg0)
 { return (pippo.*condition)(arg0)+i; }

前两个参数具有默认参数,而后两个(一个或多个)没有默认值。

我再说一遍:我不知道clang ++拒绝您的代码是否正确,或者关于可变参数的特殊规则。 但是,据我了解,clang ++会为您解决这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM