模板函数中的volatile类型推导有什么问题?

时间:2013-08-16 07:21:46

标签: c++ templates g++ volatile clang++

我有一个模板功能:

template <typename T>
inline void Acquire_Store(volatile T* ptr, T value) {
  // ...
}

当我尝试这样调用它时:

volatile Node* node;
Acquire_Store(&node, static_cast<Node*>(nullptr));

这两个g ++,clang ++编译器都是这样的:

  

推导出参数'T'的冲突类型('volatile List :: Node *'   与'List :: Node *')

调用此模板函数的正确方法是什么?

更新

现在我不确定node的类型 - 也许,我应该将其更改为Node* volatile node;

我希望变量node是易变的,而不是指向的对象。

3 个答案:

答案 0 :(得分:2)

替换和演绎在词汇上并不像宏。 volatile T*不会volatile Node**而是volatile Node* volatile*。第二个volatile来自模板。这使得T等于volatile Node*作为第一个参数。

尝试从一开始就让自己不再坚持使用不稳定的东西,但是根据实际类型将它放在一起。一个易失性指针在星形之后具有不稳定性,而不是它之前。

答案 1 :(得分:0)

编译器实际上你已经清楚地告诉了你的问题:你不能同时(实例化)T是不同的类型。那是因为你错误地施放了第二个参数。 例如,你可以像这样“修复”它:

// kate: hl C++11;
#include <iostream>

struct Node {};

template <typename T>
inline void Acquire_Store(volatile T* ptr, T value)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int main()
{
    volatile Node* node;
    Acquire_Store(&node, static_cast<volatile Node*>(nullptr));
    return 0;
}

然后输出

void Acquire_Store(volatile T*, T) [with T = volatile Node*]

但我仍然不明白你想要实现的目标......

答案 2 :(得分:0)

问题似乎是volatile限定符绑定到T的任何类型。

template <typename T>
inline void Acquire_Store(volatile T* ptr, T value)

因此,当上述T = Node *时,指向Node 的指针是易失性的, 是Node本身。为了使指向对象的volatile符合条件,它必须是T的一部分。这是一个问题,因为你的第二个参数是非易失性的 - T不能同时是易失性和非易失性的。

你可以做的是make T = volatile Node *然后使用type_traits从第二个参数中删除那个volatile限定符:

template <typename T>
inline void Acquire_Store(T *ptr, typename std::remove_volatile<T>::type value);

注意所有这些也适用于const限定符。的 Ideone demos this for const qualifier