[英]Why the templated c++ function does not compile under Visual Studio 2013
[英]Why my C++ templated function does not produce `undeclared identified` compile error?
我正在嘗試創建一個關於Lights的抽象(我正在用C ++構建游戲),我正在使用模板來做到這一點。 我現在的部分代碼是:
// Light.hpp
template <typename LightType>
void LoadLight(GLuint shaderId, const LightType& light, const std::string& glslUniformName)
{
// Load common light attributes
glUniform3f(glGetUniformLocation(lightingShader.GetProgID(), (glslUniformName + ".ambient").c_str()), light.ambient.x, light.ambient.y, light.ambient.z);
glUniform3f(glGetUniformLocation(lightingShader.GetProgID(), (glslUniformName + ".diffuse").c_str()), light.diffuse.x, light.diffuse.y, light.diffuse.z);
glUniform3f(glGetUniformLocation(lightingShader.GetProgID(), (glslUniformName + ".specular").c_str()), light.specular.x, light.specular.y, light.specular.z);
// Load specific light attributes
LoadLightSpecific<LightType>(shaderId, light, glslUniformName); // ???
}
template <typename LightType>
void LoadLightSpecific(GLuint shaderId, const LightType& light, const std::string& glslUniformName);
LoadLightSpecific
是在一個單獨的.cpp
文件中,這與我的問題無關。
我的問題是在???
。 我在定義它之前使用的是LoadLightSpecific
! 我認為這會給我一個undeclared identifier
(或類似的東西)編譯錯誤但沒有。 它正常工作。
為什么會這樣? 我覺得我錯過了一些明顯的東西。
2015年11月23日更新
因此,正如人們在評論中建議的那樣,我使用Wandbox以最少的代碼重新創建問題。 我結束了在這里 。 顯然,我的問題的答案似乎是:
“代碼不應該編譯,但不知何故MSVC解決問題”
模板在編寫模板時,您可以假設模板參數。 即:
Template<class T>
class C
{
void foo() { T.bar(); }
};
即使我們不知道T
是否實際上有一個方法bar()
,編譯器此刻接受它,因為它只是一個“模板”,而不是實際的代碼。 在您使用一些參數實例化模板時,編譯器將檢查您所假設的正確性,因為現在它必須生成代碼。
在功能的情況下,它是相同的。 必須采用相同的邏輯,除非有人在標准中找到關於它的明確陳述 ,我試圖找到並且沒有。
如果我們遵循這個邏輯,當你編寫LoadLight
的模板時,你假設存在一個名為LoadLightSpecific<T>
的函數。 換一種說法,
為什么T.bar()
和bar<T>()
在類模板中被接受,而不是在函數模板中被接受?
模板化函數不會在其模板化定義的位置進行轉換,而是在實際調用它時(類似於模板化類的實例化 ),並使用一些特定的模板參數。 如果在那個地方,所有需要的東西都可用( LoadLightSpecific
聲明),那么它將正常工作。
但是,我認為盡可能在模板定義的位置聲明事物是一種好的做法。 這樣可以更輕松地跟蹤依賴項。
對於這個特定的代碼:
如果在定義點的范圍內有一個名為LoadLightSpecific
的函數模板,則此模板定義本身有效。 (它不必具有該簽名;甚至template<int> void LoadLightSpecific();
也可以。)
原因是編譯器必須知道LoadLightSpecific
是一個模板,以便解析<
作為模板參數列表的開頭,而不是less-than運算符。
由於LoadLightSpecific<LightType>
(如果解析為template-id )依賴於模板參數,因此LoadLightSpecific
名稱查找將推遲到實例化。 (請注意,這並不意味着實例化必然會成功:不在模板定義上下文中的聲明只能通過ADL在實例化上下文中找到,而不能通過正常的非限定查找找到。)
在更一般的情況下,標准指定哪些名稱被認為依賴於模板參數而哪些不依賴於模板參數。 在模板定義時查找並綁定非依賴名稱:
如果名稱不依賴於模板參數 (如14.6.2中所定義),則該名稱的聲明(或聲明集)應在名稱出現在模板定義中的范圍內; 該名稱綁定到此時發現的聲明(或聲明),並且此綁定不受在實例化時可見的聲明的影響。
MSVC因其在該領域的不合格而聞名。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.