我有一个模板功能:
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
是易变的,而不是指向的对象。
答案 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 强>