copying constness in templates fails strangely based on type

I wrote a template to copy constness of a pointer argument for 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;
};

To be used in a method like this:

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);

I am getting different behaviors based on the type of 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"

Basically, I am getting "int" return value regardless of the constness of T, even though I verified that T gets resolved to const char.

Now if I change U to some other class, the constness is copied correctly:

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"

Even though the following asserts for the copying of constness succeed:

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");

Is this a compiler error, or am I ignoring something?


const qualifiers of scalar types are ignored on the return type of a function. For example:

static const int returns_const_int();

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

Causes

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

static assertion failed: not const

So in the cases where pointer() is declared to return a const int , it is actually returning a non-const int.

The same as not true for class types however.

链接地址: http://www.djcxy.com/p/57006.html

上一篇: 多参数函数模板的别名

下一篇: 在模板中复制常量会基于类型奇怪地失败