I am working maintenance on a program with a bunch of different structures that are fundamentally similar. I want to write a template method that utilizes SFINAE to enable calling this method from the client. When I define the template specialization inline, everything works as expected. However, when I try to move the template definition into a separate compilation unit, I run into issues. I am trying to move the template implementation into a separate file in order to enable using forward declarations for most of the dependent classes. The following is an example of what I am attempting to achieve:
// Impl.h
#pragma once
struct A {
struct {
int value;
} valueA;
};
struct B {
struct {
int value;
} valueB;
};
template<typename T>
int GetValue(T const &value);
// Impl.cpp
#include "Impl.h"
#include <type_traits>
using std::enable_if_t;
using std::remove_reference_t;
template<typename T, typename U, U(T::*Value)>
static inline int GetValueImpl(T const &value) {
return (value.*Value).value;
}
template<typename T>
enable_if_t<T::valueA, int> GetValue(T const &value) {
static constexpr auto T::*const Value = &T::valueA;
typedef remove_reference_t<decltype(value.*Value)> ValueType;
return GetValueImpl<T, ValueType, Value>(value);
}
template<typename T>
enable_if_t<T::valueB, int> GetValue(T const &value) {
static constexpr auto T::*const Value = &T::valueB;
typedef remove_reference_t<decltype(value.*Value)> ValueType;
return GetValueImpl<T, ValueType, Value>(value);
}
template<> int GetValue(A const &); // C2912 here
template<> int GetValue(B const &); // C2912 here
I am using VS2017u2, and am getting error C2912: explicitt specialization 'int GetValue(const A &)' is not a specialization of a function template. Does anyone know how to make this work with the definitions in a separate compilation unit?
Aucun commentaire:
Enregistrer un commentaire