我发现了一个类似的问题here,但它没有具体回答我的问题。我有一个简单的类模板,只需要一个参数。它不存储任何成员变量,除了简单的构造函数之外没有任何方法。根据传入的类型,我需要在构造函数中分支我的逻辑。这个类的简单版本shell看起来就像我想要做的那样。该课程将Type t
进行一些处理,并将结果存储到std::string
中。
template<class Type>
struct Test {
Test( Type t, std::string& str ) {
static_assert( std::is_arithmetic<Type>::value, "Arithmetic type required." );
if ( std::is_arithmetic<Type>::value ) { // check if type is arithmetic
// some variables here
// Note: I do not want to static_assert here if type is integral.
// If assert fails the else will not be executed.
if ( std::is_integral<type>::value ) {
// some code for integral types
} else {
// some other code for arithmetic non integral types (floating point types)
}
str = // some code.
} else {
// possibly throw some exception
}
}
};
这是基于data type
解决分支决策的适当方法吗?或者有更好的方法来做到这一点吗?
答案 0 :(得分:1)
混合标签分派和委托构造函数怎么样?
我的意思是......像
template <typename Type>
struct Test
{
Test (Type t, std::string & str, std::true_type const &,
std::true_type const &)
{ str = "case arithmetic and integral"; }
Test (Type t, std::string & str, std::true_type const &,
std::false_type const &)
{ str = "case arithmetic but not integral"; }
Test (Type t, std::string & str, std::false_type const &, ...)
{ str = "case not arithmetic"; /* + throw ? */ }
Test (Type t, std::string & str)
: Test(t, str, std::is_arithmetic<Type>{}, std::is_integral<Type>{})
{ }
};
int main ()
{
std::string str;
Test<int>(0, str);
std::cout << str << std::endl;
Test<float>(0.0f, str);
std::cout << str << std::endl;
Test<std::string>("zero", str);
std::cout << str << std::endl;
}
如果公共代码是相关的,您可以为算术类型定义单个委托构造函数,并使用正文中调用的成员进行标记调度。
那是
template <typename Type>
struct Test
{
void func (std::string & str, std::true_type const &)
{ str = "case integral"; }
void func (std::string & str, std::false_type const &)
{ str = "case not integral"; }
Test (Type t, std::string & str, std::true_type const &)
{
// variable definition and common code
func(str, /* other variables */ std::is_integral<Type>{});
// other common code
str += " plus common";
}
Test (Type t, std::string & str, std::false_type const &)
{ str = "case not arithmetic"; /* + throw ? */ }
Test (Type t, std::string & str)
: Test(t, str, std::is_arithmetic<Type>{})
{ }
};