提问人:marack 提问时间:1/29/2014 更新时间:1/29/2014 访问量:308
将“使用 std::foo”指令应用于本地构造函数初始值设定项列表 (C++)
Apply a 'using std::foo' directive to a constructor initializer list locally (C++)
问:
给定自定义类型,以下片段显示了允许函数自动选择特定于该类型的用户提供的重载的常用方法,如果不是,则允许函数从标准库中选择函数的泛型实现。
// 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
在这种情况下,有什么方法可以两全其美吗?
答:
5赞
user1508519
1/29/2014
#1
根据 using 语句可以出现在构造函数初始化列表中吗? 一种解决方法是使用私有静态函数,如下所示:
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;
}
评论
2赞
galop1n
1/29/2014
您也可以使用 lambda 来保持接近:bar2::bar2(a::b& ab) : i { [&] { using std::foo; return foo(ab); }() } {}
2赞
marack
2/3/2014
我会接受这个答案,尽管我可能更喜欢@galop1n建议的 lambda 技巧,因为它使黑客保持在本地。我们不得不诉诸这样的愚蠢事情来解决名称查找问题,这有点可惜。
上一个:必须使用完全限定的类名
评论