直到最近我還沒有寫過很多 C 模板,但我正試圖深入研究它們。修復了一位開發人員的代碼,我設法產生了一些我無法解釋的編譯器行為。這是簡化的程式。(當我嘗試進一步簡化時,我會失去那種“奇怪”的行為)。讓我們想想一些類Depender,它是模板結構依賴的一個引數。Depender可以依賴于Dependees 的串列。我有一些宏可以生成Dependency模板的特化。以下代碼塊中的點代表可能的宏擴展。我在點之前有一個前向宣告的MainDependee,在點之后有 MainDependee 的定義。
#include <type_traits>
template <typename T, typename = void>
struct IsCompleteType : std::false_type
{};
template <typename T>
struct IsCompleteType<T, std::enable_if_t<( sizeof( T ) > 0 )>> : std::true_type
{};
template<template<typename...> class List, typename Dependee>
struct DependencyInternal
{
using Type = std::conditional_t<IsCompleteType<Dependee>::value, Dependee, Dependee>;
};
template<typename... Ts> class StubList;
class MainDependee; // forward declaration
class MainDepender
{};
template<template<typename...> class List, typename Depender>
struct Dependency;
....... //here is the specialization
class MainDependee {};
int main()
{
Dependency<StubList, MainDepender> a;
}
當點被替換為
template<template<typename... Us> class List>
struct Dependency<List, MainDepender>
{
using Type = typename DependencyInternal<List, MainDependee>::Type;
};
然后在main我得到IsCompleteType<MainDependee>::value == true。
但是當點被替換為
template<>
struct Dependency<StubList, MainDepender>
{
using Type = typename DependencyInternal<StubList, MainDependee>::Type;
};
然后IsCompleteType<MainDependee>::value == false。
請告訴我,什么規則描述了這些選項之間的區別?
自己試試代碼
uj5u.com熱心網友回復:
顯式(完整)特化本身不是模板化物體,所有名稱查找等以及 ODR 都是為其完成的,就好像它不是模板一樣。MainDependee在您撰寫它的時候并不完整,因此從此時IsCompleteType<MainDependee>繼承。std::false_type
部分特化本身就是一個模板物體,將遵循模板的規則。特別是,僅當需要實體化時和在哪里需要實體化,才會從部分特化中實體化定義。在這種情況下,forDependency<StubList, MainDepender>的實體化點直接在mainwhereMainDependee完成之前。只有Type計算(因為右側依賴于模板引數)和IsCompleteType<MainDependee>實體化,所以它將繼承自std::true_type.
請注意,每個翻譯單元僅實體化一次類模板特化。如果您Dependency<StubList, MainDepender>::value在一個翻譯單元中多次使用,它總是會產生相同的值,即在需要實體化的第一個點是正確的。
此外,如果Dependency<StubList, MainDepender>::value或IsCompleteType<MainDependee>由于 的相對位置不同而在不同的翻譯單元中具有不同的值MainDependee,則您的程式將是 IFNDR(格式錯誤,不需要診斷),實際上意味著它將具有未定義的行為。
不可能使用這樣的型別特征來安全地檢查型別是否完整。出于同樣的原因,標準庫中沒有這樣的特征。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/527327.html
