具有此代码:
myProperty
在创建myProperty<int> ip{1};
myProperty<Vec3> vp1{{1, 2, 3}};
// myProperty<Vec3> vp2{1, 2, 3}; ERROR: myProperty doesn't have a matching constructor.
类型对象时:
vp2
是否有一种优雅的方法可以使myProperty
初始化工作?将Vec3
专用于WebSecurityConfigurerAdapter
实在是太过分了。
答案 0 :(得分:6)
一个简单的解决方案是使用可变参数模板构造函数:
template <typename ...P> myProperty(P &&... p) : m_value{std::forward<P>(p)...} {}
它使myProperty<Vec3> vp2{1, 2, 3};
得以编译。
它也阻止myProperty<Vec3> vp1{{1, 2, 3}};
进行编译(这似乎符合您的意图)。
此选项的问题在于,它会阻止副本构造正常工作。
(如果参数是非常量myProperty<T>
左值,则此可变参数构造函数比myProperty(const myProperty &)
更好。)
这可以通过SFINAE解决:
带有<experimental/type_traits>
的C ++ 17:
#include <experimental/type_traits>
#include <utility>
template <typename T, typename ...P> using list_constructible = decltype(T{std::declval<P>()...});
// ...
template
<
typename ...P,
typename = std::enable_if_t<std::experimental::is_detected_v<list_constructible, T, P...>>
>
myProperty(P &&... p) : m_value{std::forward<P>(p)...} {}
C ++ 14:
#include <type_traits>
#include <utility>
template <typename...> using void_t = void;
template <typename DummyVoid, template <typename...> class A, typename ...B> struct is_detected : std::false_type {};
template <template <typename...> class A, typename ...B> struct is_detected<void_t<A<B...>>, A, B...> : std::true_type {};
template <typename T, typename ...P> using list_constructible = decltype(T{std::declval<P>()...});
// ...
template
<
typename ...P,
typename = std::enable_if_t<is_detected<void, list_constructible, T, P...>::value>
>
myProperty(P &&... p) : m_value{std::forward<P>(p)...} {}