其他分享
首页 > 其他分享> > c – 一个定义规则和模板类特化

c – 一个定义规则和模板类特化

作者:互联网

popular library的作者决定实施the following design pattern

// my_traits.hpp
#include <stdio.h>
#include <assert.h>

template<typename T>
struct my_traits {
        static bool equals(const T& x, const T& y) {
                printf("base\n");
                return x == y;
        }
};

template<typename T>
void my_assert(const T& x, const T& y) {
        assert(my_traits<T>::equals(x, y));
}

现在假设库使用如下:

// main.cpp
void my_test1();
void my_test2();

int main() {
        my_test1();
        my_test2();
        return 0;
}

// my_test1.cpp
#include "my_traits.hpp"

void my_test1() {
        my_assert(-1.0, -1.0);
}

//my_test2.cpp
#include "my_traits.hpp"

#ifdef _WIN32
#include <float.h>
#define isnan _isnan
#else
#include <math.h>
#endif

template<>
struct my_traits<double> {
        static bool equals(const double& x, const double& y) {
                printf("specialization\n");
                return x == y || isnan(x) && isnan(y);
        }
};

void my_test2() {
        my_assert(-1.0, -1.0);
}

现在,

$g++ main.cpp my_test1.cpp my_test2.cpp && ./a.out
base
base

$g++ main.cpp my_test2.cpp my_test1.cpp && ./a.out
specialization
specialization

当然,无论链接顺序如何,库的用户都希望获得以下结果:

base
specialization

没有专门化或重载(内联)my_assert而不是my_traits,并且知道在包含my_traits.hpp的每个翻译单元中注入相同的特化是不可接受的(或可维护的),任何人都可以想到另一个实现所需行为的技巧修改my_traits.hpp或专门化my_assert(或使用kludgy包装器类为double :))?

解决方法:

§14.7.3[temp.expl.spec] / p6(重点补充):

If a template, a member template or a member of a class template is
explicitly specialized then that specialization shall be declared
before the first use of that specialization that would cause an
implicit instantiation to take place, in every translation unit in
which such a use occurs
; no diagnostic is required. If the program
does not provide a definition for an explicit specialization and
either the specialization is used in a way that would cause an
implicit instantiation to take place or the member is a virtual member
function, the program is ill-formed, no diagnostic required.

标签:generic-programming,c,c11,cppunit
来源: https://codeday.me/bug/20190830/1768045.html