簡體   English   中英

C ++模板按非類型參數類型的特化

[英]C++ Template specialization by type of non-type parameter

根據非類型成員的類型,相同模板函數的變體是否有效?

template<typename T, unsigned int V>
void f(unsigned int& v) { v = V; }

template<typename T, bool B>
void f(bool& b) { b = B; }

目的是讓人能夠打電話

unsigned int meaningOfLife;
f<sometype, 42>(meaningOfLife);

bool areYouAlive;
f<sometype, true>(areYouAlive);

鏗鏘聲和gcc聲音沉默,但MSVC報道

warning C4305: 'specialization': truncation from 'int' to 'bool'

我想避免要求指定常量類型:

f<sometype, bool, true>

並希望確保常量值和目標值匹配。

---- mcve ----

#include <iostream>

template<unsigned int V>
void f(unsigned int& v) { v = V; }

template<bool B>
void f(bool& b) { b = B; }

int main()
{
    unsigned int u { 0 };
    bool b { false };

    f<42>(u);
    f<true>(b);

    std::cout << u << b;
}

Rextester示例: http ://rextester.com/VIGNP16100

Warning(s):
source_file.cpp(14): warning C4305: 'specialization': truncation from 'int' to 'bool'
/LIBPATH:C:\boost_1_60_0\stage\lib 
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64
421

簡答:代碼沒問題,MSVC發出虛假警告。

MSVC和g ++都有非類型模板參數匹配中的錯誤,但它們確實為您的特定示例選擇了正確的錯誤。


長答案:使用非類型模板參數重載功能模板是可以的。

但是, 模板參數與模板聲明的匹配無法正常工作(無論如何)。 所有匹配的模板都輸入到重載分辨率。 在任何階段,它都不喜歡“完全匹配”。

根據C ++ 17 [temp.arg.nontype /] 2,允許轉換的常量表達式 這意味着,例如:

  • 42匹配intunsigned int
  • 42u匹配intunsigned int
  • 1u匹配unsigned intintbool

請注意,轉換的常量表達式不能包含縮小轉換,並且intbool正在縮小,除非該值是值01的常量表達式。 所以42bool不匹配。 (參考:C ++ 17 [expr.const] / 4)。

如果我們有以下設置:

template<unsigned int V> void g() {}
template<bool B> void g() {}

然后正確的行為是:

  • g<42>()調用g<unsigned int>
  • g<1>()含糊不清。
  • g<1u>()含糊不清。

MSVC 2017和g ++ 7,8都錯誤地允許g<42>匹配g<bool> ,並且報告g<42>不明確。

MSVC會在生成無效匹配時發出警告; g ++根本不提供診斷。 如果我們刪除unsigned int overload,那么g ++會默默地接受無效代碼而不進行診斷。


在您的代碼中有一個非const左值引用參數:

template<unsigned int V>  void h(unsigned int&) {}
template<bool B>          void h(bool&) {}

這有所不同,因為重載決策可以根據函數參數進行選擇。 致電:

unsigned int m;
h<1u>(m);

然后h兩個重載都進入重載決策,然后h<unsigned int>獲勝,因為h<bool>(m)將無效。

如上所述,呼叫h<42>(m); 在第一階段贏,因為這不能匹配h<bool> ; 但是在MSVC ++(和g ++)中,它錯誤地允許h<bool>在這個階段進行,但是在h<1u>情況下修剪它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM