C++11 使用 is_pointer 适当地取消引用指针[重复]

问题描述 投票:0回答:1

我用 C++ 编写了一个比较函数,仅当 T 是指针类型时才应取消引用:

template<class T> bool compare(const T& left, const T& right)
 {
 if (is_pointer<T>::value)
   return *left <= *right;
 return left <= right;
 }

但是当 T 为 int 时它会尝试取消引用:

invalid type argument of unary ‘*’ (have ‘int’)
c++
1个回答
0
投票

问题在于,即使从未输入 if 语句,该语句

return *left <= *right;

仍然必须正确(语法和语义上)。

int
没有一元
*
运算符,因此它在语义上无效。

同样,也不可能写出以下内容(与您的情况类似):

// invalid semantics in if statement
if (false) 0 = 0;
// invalid syntax in if statement
if (false) #@$#@ #@%#@ gjrwiuthui 4325@#$%@#$%;

C++17 解决方案

使其工作的一种方法是使用

if constexpr
(C++17),如果条件为 false,它将将该语句视为“丢弃的语句”。 这意味着编译器根本不会尝试将
*
应用于
int
;它将完全删除该部分:

if constexpr (std::is_pointer_v<T>)
   return *left <= *right;

另请参阅 “if constexpr()”与“if()”之间的区别

C++11 解决方案

您可以有两个不同的功能模板;仅当参数是指针时才能调用。

template<class T>
typename std::enable_if<is_pointer<T>::value, bool>::type
compare(const T& left, const T& right)
{
    return *left <= *right;
}

template<class T>
typename std::enable_if<!is_pointer<T>::value, bool>::type
compare(const T& left, const T& right)
{
    return left <= right;
}

另请参阅 std::enable_if 如何工作?

© www.soinside.com 2019 - 2024. All rights reserved.