我应该如何有条件地启用构造函数?
How should I conditionally enable a constructor?
我正在努力实现这样的目标:
template<typename Bar>
class foo
{
public:
template<class = std::enable_if_t<std::is_constructible<Bar, int>::value>>
foo(int x)
: m_bar(x)
{ }
private:
Bar m_bar;
};
这会产生行为
foo<int> a; // no error
foo<int> b(0); // no error
foo<std::string> c; // no error
foo<std::string> d(0); // error: none of the 3 overloads could convert all the argument types
符合预期。这个解决方案有什么缺点吗?我不喜欢的是在任何一种情况下 foo::foo(int)
都存在。我知道我可以在 foo
本身的模板参数列表中使用 enable_if
并针对这两种情况专门化 foo
,但我不想复制通用代码。
那么,这是最好的(或至少是明智的)选择吗?
Is there any disadvantage of this solution?
目前,替换发生在直接上下文之外,因此一旦您尝试使用 [=12] 无法构造的类型实例化 foo
,您的方法就会 cause a hard compilation error =].
要引入直接上下文,您需要一个虚拟参数:
template <typename T = Bar
// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~v
, typename = std::enable_if_t<std::is_constructible<T, int>::value>>
foo(int x)
: m_bar(x)
{ }
我正在努力实现这样的目标:
template<typename Bar>
class foo
{
public:
template<class = std::enable_if_t<std::is_constructible<Bar, int>::value>>
foo(int x)
: m_bar(x)
{ }
private:
Bar m_bar;
};
这会产生行为
foo<int> a; // no error
foo<int> b(0); // no error
foo<std::string> c; // no error
foo<std::string> d(0); // error: none of the 3 overloads could convert all the argument types
符合预期。这个解决方案有什么缺点吗?我不喜欢的是在任何一种情况下 foo::foo(int)
都存在。我知道我可以在 foo
本身的模板参数列表中使用 enable_if
并针对这两种情况专门化 foo
,但我不想复制通用代码。
那么,这是最好的(或至少是明智的)选择吗?
Is there any disadvantage of this solution?
目前,替换发生在直接上下文之外,因此一旦您尝试使用 [=12] 无法构造的类型实例化 foo
,您的方法就会 cause a hard compilation error =].
要引入直接上下文,您需要一个虚拟参数:
template <typename T = Bar
// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~v
, typename = std::enable_if_t<std::is_constructible<T, int>::value>>
foo(int x)
: m_bar(x)
{ }