我有一个模板化函数,可以在浮点数或(无符号)整数类型上运行,如下所示:
template< typename T >
void typedFunc( T& data )
{
// .... lots of code ....
if( std::numeric_limits<T>::is_integer )
{
data = data << 8;
// .... do some processing ....
}
else
{
// .... do some slightly different processing ....
}
// .... lots more code ....
}
当我将该函数用于浮点类型时,我从位移中得到编译错误,因为您无法移位浮点数。对于一个浮点数,这段代码永远不会执行,并且(希望)被优化掉,所以只需要编译。我可以通过将data
强制转换为int来摆脱编译错误,但是当与整数类型一起使用时,它会改变函数的行为。
如何在不改变其行为的情况下编译此代码?
TIA
答案 0 :(得分:4)
您可以拆分方法并专门化非常见部分:
//Answer Question
public function answer()
{
//Validate form input
$this->form_validation->set_rules('question_id', '', 'integer|required');
$this->form_validation->set_rules('answer_text', 'lang:answer_text', 'trim|required|xss_clean');
if ($this->form_validation->run() == true)
{
$question_exists = $this->questions->select_by_id($this->input->post('question_id'), 1);
//Check if question exists
if($question_exists) {
//Add to database
$answer_id = $this->answers->create(
array(
'question_id' => $this->input->post('question_id'),
'answer_text' => $this->input->post('answer_text'),
'commentator_id' => ($this->ion_auth->logged_in()) ? $this->the_user->id : 0,
'answer_date' => time()
)
);
if ($answer_id)
{
$data['answer'] = $this->answers->select_by_id($answer_id);
if($this->ion_auth->logged_in())
$this->users->update(array('answers' => $this->the_user->answers + 1), $this->the_user->id);
//check if answer is posted on a category page or profile page
if ($question_exists->asked_id != 0) {
$this->questions->update(array('question_status' => 1), $question_exists->question_id);
$data['answer_profile'] = true;
} else {
$data['answer_profile'] = false;
}
$this->load->view('blocks/new_answer', $data);
}
}
}
}
答案 1 :(得分:1)
模板函数的整个主体需要对给定的参数集有效,即使某些类型的某些代码永远不会被执行。
解决此问题的一种简单方法是将特定于类型的处理分离为单独的函数和标记分派,以便从中进行选择:
template <typename T>
void doProcessing (std::true_type, T& data);
template <typename T>
void doProcessing (std::false_type, T& data);
//usage
doProcessing (std::is_integral<T>{}, data);
答案 2 :(得分:1)
您应该使用标记分发来拆分不兼容的代码,如下所示:
template<typename T>
void doShift(T& data, std::false_type)
{ data = data << 8; }
template<typename T>
void doShift(T& data, std::true_type)
{ /* do something with float */ }
template< typename T >
void typedFunc( T& data )
{
// .... lots of code ....
doShift(data, typename std::is_floating_point<T>::type{});
// .... lots more code ....
}