5

我有一个模板功能:

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是易变的,但不是指向对象。

4

3 回答 3

2

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

尽量让自己不要总是一开始就粘着 volatile,而是根据实际类型把它放在它所属的地方。volatile 指针在星号之后有 volatile,而不是在星号之前。

于 2013-08-16T08:49:46.377 回答
0

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

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

因此,T = Node *对于上述情况,它是指向 Node的指针,而不是Node 本身。要使指向的对象 volatile 合格,它必须是 T 的一部分。这会带来一个问题,因为您的第二个参数是非易失性的——T 不能同时是易失性和非易失性的。

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

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

请注意,所有这些也适用于 const 限定符。Ideone 对 const qualifier 进行了演示

于 2013-08-16T08:46:00.530 回答
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*]

但我仍然不明白你想要达到什么目的......

于 2013-08-16T08:06:37.867 回答