Template Specialization for std :: atomic <double> &

I have this 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" );
}

I get this compiler error:

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>]’

How to transfer a link std::atomic<double>to a specialized template? In a normal function, this is possible.

+4
source share
3 answers

In this case, it Twill be displayed as std::atomic<double>, but not std::atomic<double> &. Then the primary template will always be called instead of specialization.

You can explicitly specify a template argument, for example.

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

Or use function template overloading.

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

Your problem is here:

template<typename T> void assertVariableHasBeenSet( T, const char * );

The main template will be selected because it myDoubleAtomicis of type std::atomic<double>, not std::atomic<double> &.

T , . std::atomic , .

, :

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

, , - . T std::atomic<double>. . , . std::atomic<double>& .

( ):

  • T&&, T std::atomic<double>&.
  • , .. template<> <std::atomic<double>&> .
+1

Source: https://habr.com/ru/post/1690895/


All Articles