提问人:buzzysin 提问时间:6/24/2023 最后编辑:JeJobuzzysin 更新时间:6/24/2023 访问量:79
如何为专用模板类提供更紧凑的定义?
How do I provide a more compact definition for the specialized template classes?
问:
请考虑以下情况:
template <
typename T,
bool B = std::is_default_constructible_v<T>>
class toy_example;
template<typename T>
class toy_example<T, true>
{
public:
toy_example() = default; // e.g. for default constructible types
toy_example(const T& value);
public:
void monomorphic(T);
private:
T m_value;
};
template<typename T>
class toy_example<T, false>
{
public:
toy_example() = delete; // e.g. for non-default constructible types
toy_example(const T& value); // Repeated declaration
public:
void monomorphic(T); // Repeated declaration
private:
T m_value;
};
// Implementation
template<typename T>
toy_example<T, true>::toy_example(const T& value) : m_value(value) {}
// (Unnecessary?) Repetition
template<typename T>
toy_example<T, false>::toy_example(const T& value) : m_value(value) {}
template<typename T>
toy_example<T, true>::monomorphic(T)
{
std::cout << "Behaviour is the same despite specialisation.\n";
// (P.S) - This is intended behaviour
}
// (Unnecessary?) Repetition
template<typename T>
toy_example<T, false>::monomorphic(T)
{
std::cout << "Behaviour is the same despite specialisation.\n";
// (P.S) - This is intended behaviour
}
如何通过为我希望以相同方式运行的函数(在本例中为初始化构造函数和函数)提供单个定义来为此类提供更紧凑的定义?monomorphic
我这样做的动机是,在我的代码库中,代码有点冗长,我宁愿不必要地复制它。monomorphic(T)
我知道解决方案可能涉及使用某种基类,但我不确定如何处理这个问题。
答:
5赞
JeJo
6/24/2023
#1
如何通过为我希望以相同方式表现的函数(在本例中为初始化构造函数和单态函数)提供单个定义,为此类提供更紧凑的定义?
由于您使用的是 c++17,我将使用 if constexpr
功能,通过该功能可以将两个实现保持在同一个函数体中。
此外,默认构造函数(和其他通用代码)可以针对同一类中的每个案例进行 SFINAEd。
类似的东西。
class ExampleClass
{
public:
template<typename U = T>
ExampleClass(std::enable_if_t<std::is_default_constructible_v<U>>* = 0)
{} // enabled only for default constructible types
template<typename U = T>
ExampleClass(
std::enable_if_t<!std::is_default_constructible_v<U>>* = 0
) = delete; // For non-default constructible types
ExampleClass(const T& value)
: m_value{ value } {}
public:
void monomorphic()
{
if constexpr (std::is_default_constructible_v<T>)
{
std::cout << "default_constructible Impli\n";
}
else
{
std::cout << "Non-default_constructible Impli\n";
}
}
private:
T m_value;
};
或者,您显然可以在 和 中拥有通用实现,派生类(即启用/禁用 )可以具有专用化功能,如下所示:Base
std::is_default_constructible_v
monomorphic()
// Common base class
template<typename T> class Base
{
public:
template<typename U = T>
Base(std::enable_if_t<std::is_default_constructible_v<U>>* = 0)
{} // enabled only for default constructible types
template<typename U = T>
Base(std::enable_if_t<!std::is_default_constructible_v<U>>* = 0)
= delete; // for non default constructible types
Base(const T& value)
: m_value{ value } {}
private:
T m_value;
};
template <typename T, typename Enable = void> class Derived;
// specialization for true case
template<typename T>
class Derived<T,
std::enable_if_t<std::is_default_constructible_v<T>>>
: public Base<T>
{
public:
Derived() = default;
using Base<T>::Base;
void monomorphic(){ std::cout << "default_constructible Impli\n"; }
};
// specialization for false case
template<typename T>
class Derived<T,
std::enable_if_t<!std::is_default_constructible_v<T>>>
: public Base<T>
{
public:
using Base<T>::Base;
void monomorphic() { std::cout << "Non-default_constructible Impli\n"; }
};
评论
0赞
buzzysin
6/24/2023
感谢您的编辑和回答。下次我会尝试更好地格式化我的问题:<
评论