在模板中复制constness会因类型而奇怪地失败

时间:2016-03-20 02:06:51

标签: c++ templates c++11 stl

我写了一个模板来复制C ++ 11指针参数的常量:

template<typename S, typename D>
struct copy_const {
    typedef typename std::conditional<std::is_const<S>::value,
          typename std::add_const<D>::type,
          typename std::remove_const<D>::type>::type type;
};

用于这样的方法:

template<typename T, typename U,
    class=typename std::enable_if<std::is_convertible<T, char>::value>::type>
typename copy_const<T, U>::type pointer(T*, U);

我根据U的类型得到不同的行为:

static_assert(std::is_same<decltype(pointer((char *)0, 0)), int>::value,
              "bad pointer 1");
static_assert(std::is_same<decltype(pointer((const char *)0, 0)), const int>::value,
              "bad pointer 2");
static_assert(std::is_same<decltype(pointer((const char *)0, 0)), int>::value,
              "bad pointer 3");

error: static_assert failed "bad pointer 2"

基本上,无论T的常量如何,我都得到“int”返回值,即使我确认T被解析为const char。

现在,如果我将U更改为其他类,则会正确复制const:

struct V{};
static_assert(std::is_same<decltype(pointer((char *)0, V())), V>::value,
              "bad pointer 4");
static_assert(std::is_same<decltype(pointer((const char *)0, V())), const V>::value,
              "bad pointer 5");
static_assert(std::is_same<decltype(pointer((const char *)0, V())), V>::value,
              "bad pointer 6");

error: static_assert failed "bad pointer 6"

即使以下断言复制constness成功了:

static_assert(std::is_same<decltype(0), int>::value, "bad type");
static_assert(std::is_same<std::add_const<int>::type, const int>::value,
              "bad const 1");
static_assert(std::is_same<const int, copy_const<const int, int>::type>::value,
              "bad const 2");

这是编译错误,还是我忽略了什么?

1 个答案:

答案 0 :(得分:3)

标量类型的const限定符在函数的返回类型上被忽略。例如:

static const int returns_const_int();

int main()
{
    static_assert(
        std::is_same<decltype(returns_const_int()), const int>::value,
        "not const"
    );
}

原因

warning: type qualifiers ignored on function return type
    [-Wignored-qualifiers]
static const int returns_const_int();

static assertion failed: not const

因此,在声明pointer()返回const int的情况下,它实际上返回一个非const int。

然而,对于类类型则不然。