acm*_*acm 33 c++ copy-constructor variadic-templates c++11
我有一个模板'Foo',它拥有一个T,我希望它有一个可变参数构造函数,将它的参数转发给T的构造函数:
template<typename T>
struct Foo {
Foo()
: t() {}
Foo(const Foo& other)
: t(other.t) {}
template<typename ...Args>
Foo(Args&&... args)
: t(std::forward<Args>(args)...) {}
T t;
};
Run Code Online (Sandbox Code Playgroud)
但是,这会导致Foo无法复制:
int main(int argc, char* argv[]) {
Foo<std::shared_ptr<int>> x(new int(42));
decltype(x) copy_of_x(x); // FAILS TO COMPILE
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
因为,根据这个答案,参数的非常量导致可变参数构造函数更好地匹配.出于显而易见的原因,我不想强制我的调用者使用const_cast.
我找到的一个可能的解决方案是为Foo编写一个"复制构造函数",它采用非const Foo并使用构造函数转发:
Foo(Foo& other)
: Foo(const_cast<const Foo&>(other)) {}
Run Code Online (Sandbox Code Playgroud)
当定义了这个构造函数时,事情再次起作用:现在首选非const Foo参数copy ctor.然而,这对我来说似乎非常粗略,因为这种"治愈"似乎比疾病更糟糕.
是否有另一种方法来实现这种效果,表明自然拷贝构造函数应该优先于可变参数构造函数?如果没有,定义这个非const参数复制构造函数会有什么不利后果吗?
Luc*_*lle 14
你可以使用一些丑陋的SFINAE std::enable_if,但我不确定它比你的初始解决方案更好(事实上,我很确定它更糟糕!):
#include <memory>
#include <type_traits>
// helper that was not included in C++11
template<bool B, typename T = void> using disable_if = std::enable_if<!B, T>;
template<typename T>
struct Foo {
Foo() = default;
Foo(const Foo &) = default;
template<typename Arg, typename ...Args, typename = typename
disable_if<
sizeof...(Args) == 0 &&
std::is_same<typename
std::remove_reference<Arg>::type,
Foo
>::value
>::type
>
Foo(Arg&& arg, Args&&... args)
: t(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
T t;
};
int main(int argc, char* argv[]) {
Foo<std::shared_ptr<int>> x(new int(42));
decltype(x) copy_of_x(x);
decltype(x) copy_of_temp(Foo<std::shared_ptr<int>>(new int));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2504 次 |
| 最近记录: |