13

给定自定义类型,以下片段显示了允许函数自动选择用户提供的特定于该类型的重载的常用方法,或者如果没有,则从标准库中选择函数的通用实现。

// assume std::foo is a real function template returning an int
namespace a {
  struct b { };    
  int foo(b& ab) { ... }
}

int bar(a::b& ab)
{
  using std::foo;
  return foo(ab);
}

这种方法将自动选择a::foo是否std::foo存在。

我的问题是,当有问题的调用是构造函数的初始化程序列表的一部分时,是否有可能实现类似的行为?

struct bar2
{
  bar2(a::b& ab);
  int i;
};

bar2::bar2(a::b& ab)
  : i{foo(ab)} // want a::foo if available, else std::foo
{ }

显然放入using std::foo构造函数体为时已晚。但是,如果我把它放在构造函数定义之前,我会引入std::foo全局命名空间,这也是不可取的。

在这种情况下,有没有办法两全其美?

4

1 回答 1

5

根据使用语句可以出现在构造函数初始化列表中吗?一种解决方法是使用私有静态函数,如下所示:

struct bar2
{
  bar2(a::b& ab);
  int i;
  private:
  static int wrapper(a::b& f)
  {
      using std::foo;
      return foo(f);
  }
};

bar2::bar2(a::b& ab)
  : i{wrapper(ab)} // want a::foo if available, else std::foo
{ }

在这种情况下,您可以保留初始化列表的好处,而无需将初始化移动到构造函数的主体。上面链接的问题中的 OP 声称它不提供 ADL,但它似乎对我有用。要测试,只需删除:

int bar(foo f)
{
    std::cout << "custom.\n";
    return 0;
}
于 2014-01-29T02:07:52.190 回答