std :: atomic <double>&amp;的模板专门化

时间:2017-12-16 11:23:01

标签: c++ c++11 templates template-specialization

我有这个MCVE:

#include <stdio.h>
#include <atomic>

template<typename T> void assertVariableHasBeenSet( T, const char * );
template<>           void assertVariableHasBeenSet<std::atomic<double> &>
                                                        ( std::atomic<double> & myDouble, 
                                                          const char * variableName 
                                                        )
{
    printf( "Double:%s=%f\n", variableName,  myDouble.load() );
};

int main()
{
    std::atomic<double> myDoubleAtomic  {23.45};

    assertVariableHasBeenSet( myDoubleAtomic,   "myDoubleAtomic" );
}

我收到此编译器错误:

getType.cpp: In function ‘int main()’:
getType.cpp:14:61: error: use of deleted function ‘std::atomic<_Tp>::atomic(const std::atomic<_Tp>&) [with _Tp = double]’
  assertVariableHasBeenSet( myDoubleAtomic, "myDoubleAtomic" );
                                                             ^
In file included from getType.cpp:2:0:
/usr/local/include/c++/4.9.4/atomic:169:7: note: declared here
       atomic(const atomic&) = delete;
       ^
getType.cpp:4:27: error:   initializing argument 1 of ‘void assertVariableHasBeenSet(T, const char*) [with T = std::atomic<double>]’

如何将std::atomic<double>引用传递给专用模板? 在正常的功能中,它是可能的。

3 个答案:

答案 0 :(得分:5)

对于这种情况,<script src="~/Scripts/jquery-1.10.2.min.js"></script> <script src="~/typeahead.js/typeahead.jquery.js"></script> <script src="~/typeahead.js/bloodhound.min.js"></script> <script> $(document).ready(function() { // Instantiate the Bloodhound suggestion engine var serials = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('serialNumbers'), queryTokenizer: Bloodhound.tokenizers.whitespace, remote: { url: 'http://localhost:49497/DemoType/GetSerialNo?query=%QUERY', filter: function (data) { // Map the remote source JSON array to a JavaScript object array return $.map(data.serialNumbers, function (serial) { return { value: serial }; }); } } }); // Initialize the Bloodhound suggestion engine serials.initialize(); // Instantiate the Typeahead UI $('.typeahead').typeahead(null, { displayKey: 'value', source: serials.ttAdapter() }); }); </script> 将推断为T,而不是std::atomic<double>。然后将始终调用主模板而不是专业化。

您可以明确指定模板参数,例如

std::atomic<double> &

或申请重载。

assertVariableHasBeenSet<std::atomic<double> &>(myDoubleAtomic, "myDoubleAtomic");

答案 1 :(得分:2)

您的问题在这里:

pyautogui.click

将选择主要模板,因为template<typename T> void assertVariableHasBeenSet( T, const char * ); 的类型为myDoubleAtomic,而非std::atomic<double>

主模板尝试按值传递std::atomic<double> &,需要副本。 T有一个已删除的副本构造函数,导致该错误。

您应该告诉编译器明确使用哪种类型:

std::atomic

答案 2 :(得分:2)

首先要做的是重载解析。在重载解析期间,类型T被推断为std::atomic<double>。接下来确定适当的专业化。没有专门的版本,使用主模板。永远不会通过演绎找到std::atomic<double>&的专业化。

有两种方法可以解决问题(我没有考虑明确指定类型的解决方案):

  1. 声明主要模板以获取转发引用T&&,因为这会将T推断为std::atomic<double>&
  2. 使用重写代替模板专精,即删除函数名后的template<><std::atomic<double>&>