Dependent names
template μ μ λ΄λΆμμλ( class template κ³Ό function template λͺ¨λ) μΌλΆ κ΅¬μ± μμμ μλ―Έκ° μΈμ€ν΄μ€νλ§λ€ λ€λ₯Ό μ μμ΅λλ€. νΉν, νμ κ³Ό ννμμ νμ ν νλ¦Ώ λ§€κ°λ³μμ νμ κ³Ό μμ ν νλ¦Ώ λ§€κ°λ³μμ κ°μ μμ‘΄ν μ μμ΅λλ€.
template<typename T> struct X : B<T> // "B<T>"λ Tμ μ’ μμ μ { typename T::A* pa; // "T::A"λ Tμ μ’ μμ μ // ("typename" μ¬μ©μ μλ―Έλ μλ μ°Έμ‘°) void f(B<T>* pb) { static int i = B<T>::i; // "B<T>::i"λ Tμ μ’ μμ μ pb->j++; // "pb->j"λ Tμ μ’ μμ μ } };
μ΄λ¦ lookup κ³Ό λ°μΈλ©μ μ’ μ μ΄λ¦κ³Ό λΉμ’ μ μ΄λ¦μ λν΄ λ€λ₯΄κ² μ μ©λ©λλ€.
λͺ©μ°¨ |
λ°μΈλ© κ·μΉ
λΉμ’ μ μ΄λ¦(non-dependent names)μ ν νλ¦Ώ μ μ μμ μμ μ‘°νλκ³ λ°μΈλ©λ©λλ€. μ΄ λ°μΈλ©μ ν νλ¦Ώ μΈμ€ν΄μ€ν μμ μ λ λμ λ§€μΉκ° μ‘΄μ¬νλλΌλ μ μ§λ©λλ€:
ν νλ¦Ώ νΉμνμ μ μ 컨ν μ€νΈμ μΈμ€ν΄μ€ν μ§μ μ¬μ΄μμ λΉμμ‘΄μ μ΄λ¦(non-dependent name)μ μλ―Έκ° λ³κ²½λλ κ²½μ°, νλ‘κ·Έλ¨μ νμ μ€λ₯μ΄λ©° μ§λ¨μ νμνμ§ μμ΅λλ€. μ΄λ λ€μκ³Ό κ°μ μν©μμ λ°μν μ μμ΅λλ€:
- λΉμμ‘΄μ μ΄λ¦μ μ¬μ©λ νμ μ΄ λΆμμ ν νμ μΌλ‘ μ μ μ§μ μ μ‘΄μ¬νμ§λ§, μΈμ€ν΄μ€ν μ§μ μμλ μμ ν νμ μ΄ λλ κ²½μ°
|
(C++17λΆν°) |
- μΈμ€ν΄μ€νκ° μ μ μ§μ μμ μμ§ μ μλμ§ μμ κΈ°λ³Έ μΈμλ κΈ°λ³Έ ν νλ¦Ώ μΈμλ₯Ό μ¬μ©νλ κ²½μ°
- μΈμ€ν΄μ€ν μ§μ μμ constant expression μ΄ μ μνμ΄λ λΉλ²μ μ΄κ±°ν const κ°μ²΄μ κ° , constexpr κ°μ²΄μ κ°, μ°Έμ‘°μ κ°, λλ constexpr ν¨μμ μ μ (since C++11) μ μ¬μ©νκ³ , ν΄λΉ κ°μ²΄ /μ°Έμ‘°/ν¨μ (since C++11) κ° μ μ μ§μ μμ μ μλμ§ μμ κ²½μ°
- ν νλ¦Ώμ΄ μΈμ€ν΄μ€ν μ§μ μμ λΉμμ‘΄μ ν΄λμ€ ν νλ¦Ώ νΉμν λλ λ³μ ν νλ¦Ώ νΉμν (since C++14) λ₯Ό μ¬μ©νκ³ , μ΄ μ¬μ©λ ν νλ¦Ώμ΄ μ μ μ§μ μμ μ μλμ§ μμ λΆλΆ νΉμνλ‘λΆν° μΈμ€ν΄μ€νλμκ±°λ μ μ μ§μ μμ μ μΈλμ§ μμ λͺ μμ νΉμνλ₯Ό μ§μΉνλ κ²½μ°
μ’ μ μ΄λ¦μ λ°μΈλ©μ μ‘°νκ° μνλ λκΉμ§ μ°κΈ°λ©λλ€.
μ‘°ν κ·μΉ
ν νλ¦Ώμμ μ¬μ©λλ μ’ μ μ΄λ¦(dependent name)μ μ‘°ν(lookup) λ ν νλ¦Ώ μΈμκ° μλ €μ§ λκΉμ§ μ§μ°λλ©°, μ΄ μμ μμ
- non-ADL lookupλ ν νλ¦Ώ μ μ 컨ν μ€νΈμμ λ³Ό μ μλ μΈλΆ λ§ν¬λ₯Ό κ°μ§ ν¨μ μ μΈμ κ²μ¬ν©λλ€
- ADL λ ν νλ¦Ώ μ μ 컨ν μ€νΈ λλ ν νλ¦Ώ μΈμ€ν΄μ€ν 컨ν μ€νΈμμ λ³Ό μ μλ μΈλΆ λ§ν¬λ₯Ό κ°μ§ ν¨μ μ μΈμ κ²μ¬ν©λλ€
(λ€μ λ§ν΄, ν νλ¦Ώ μ μ μ΄νμ μλ‘μ΄ ν¨μ μ μΈμ μΆκ°νλλΌλ ADLμ ν΅ν κ²½μ°λ₯Ό μ μΈνκ³ λ ν΄λΉ ν¨μλ₯Ό λ³Ό μ μμ΅λλ€).
μ΄ κ·μΉμ λͺ©μ μ ν νλ¦Ώ μΈμ€ν΄μ€νμ λν ODR μλ°μ λ°©μ§νλ λ° λμμ μ£ΌκΈ° μν¨μ λλ€:
// μΈλΆ λΌμ΄λΈλ¬λ¦¬ namespace E { template<typename T> void writeObject(const T& t) { std::cout << "Value = " << t << '\n'; } } // λ²μ λ¨μ 1: // νλ‘κ·Έλλ¨Έ 1μ E::writeObjectκ° vector<int>μ λμνλλ‘ νμ©νλ € ν¨ namespace P1 { std::ostream& operator<<(std::ostream& os, const std::vector<int>& v) { for (int n : v) os << n << ' '; return os; } void doSomething() { std::vector<int> v; E::writeObject(v); // μ€λ₯: P1::operator<<λ₯Ό μ°Ύμ§ λͺ»ν¨ } } // λ²μ λ¨μ 2: // νλ‘κ·Έλλ¨Έ 2λ E::writeObjectκ° vector<int>μ λμνλλ‘ νμ©νλ € ν¨ namespace P2 { std::ostream& operator<<(std::ostream& os, const std::vector<int>& v) { for (int n : v) os << n << ':'; return os << "[]"; } void doSomethingElse() { std::vector<int> v; E::writeObject(v); // μ€λ₯: P2::operator<<λ₯Ό μ°Ύμ§ λͺ»ν¨ } }
μ μμ μμ, μΈμ€ν΄μ€ν 컨ν
μ€νΈλ‘λΆν°
operator<<
μ λν λΉ-ADL νμμ΄ νμ©λλ€λ©΄,
E
::
writeObject
<
vector
<
int
>>
μ μΈμ€ν΄μ€νλ λ κ°μ§ μλ‘ λ€λ₯Έ μ μλ₯Ό κ°μ§κ² λ κ²μ
λλ€: νλλ
P1
::
operator
<<
λ₯Ό μ¬μ©νκ³ λ€λ₯Έ νλλ
P2
::
operator
<<
λ₯Ό μ¬μ©ν©λλ€. μ΄λ¬ν ODR μλ°μ λ§μ»€μ μν΄ κ°μ§λμ§ μμ μ μμΌλ©°, λ μΈμ€ν΄μ€ λͺ¨λμμ μ΄λ νμͺ½μ΄ μ¬μ©λλ κ²°κ³Όλ₯Ό μ΄λν μ μμ΅λλ€.
ADLμ΄ μ¬μ©μ μ μ λ€μμ€νμ΄μ€λ₯Ό κ²μ¬νλλ‘ νλ €λ©΄, std::vector λ₯Ό μ¬μ©μ μ μ ν΄λμ€λ‘ λ체νκ±°λ ν΄λΉ μμ νμ μ΄ μ¬μ©μ μ μ ν΄λμ€μ¬μΌ ν©λλ€:
namespace P1 { // Cκ° P1 λ€μμ€νμ΄μ€μ μ μλ ν΄λμ€μΈ κ²½μ° std::ostream& operator<<(std::ostream& os, const std::vector<C>& v) { for (C n : v) os << n; return os; } void doSomething() { std::vector<C> v; E::writeObject(v); // OK: writeObject(std::vector<P1::C>)λ₯Ό μΈμ€ν΄μ€νν¨ // ADLμ ν΅ν΄ P1::operator<<λ₯Ό μ°Ύμ } }
μ°Έκ³ : μ΄ κ·μΉμ νμ€ λΌμ΄λΈλ¬λ¦¬ νμ μ λν μ°μ°μ μ€λ²λ‘λ©μ λΉμ€μ©μ μΌλ‘ λ§λλλ€:
#include <iostream> #include <iterator> #include <utility> #include <vector> // λμ μμ΄λμ΄: μ μ λ€μμ€νμ΄μ€μ μ°μ°μλ₯Ό μ μνμ§λ§ μΈμλ std::μ μμ std::ostream& operator<<(std::ostream& os, std::pair<int, double> p) { return os << p.first << ',' << p.second; } int main() { typedef std::pair<int, double> elem_t; std::vector<elem_t> v(10); std::cout << v[0] << '\n'; // OK: μΌλ° μ‘°νκ°Β ::operator<<λ₯Ό μ°Ύμ std::copy(v.begin(), v.end(), std::ostream_iterator<elem_t>(std::cout, " ")); // μ€λ₯: std::ostream_iterator μ μ μ§μ μμμ μΌλ° μ‘°νμ // ADL λͺ¨λ std λ€μμ€νμ΄μ€λ§ κ³ λ €νλ©°, // std::operator<<μ μ¬λ¬ μ€λ²λ‘λλ₯Ό μ°Ύκ² λμ΄ μ‘°νκ° μλ£λ¨ // μ΄ν μ€λ²λ‘λ ν΄κ²° κ³Όμ μμ elem_tμ λν operator<<λ₯Ό // μ‘°νλ‘ μ°Ύμ μ§ν©μμ λ°κ²¬νμ§ λͺ»ν¨ }
μ°Έκ³ : μ’ μ μ΄λ¦μ λν μ νλ μ‘°ν(λ°μΈλ©μ μλ)λ ν νλ¦Ώ μ μ μμ μλ νμμ λ°λΌ μνλλ©°, μ΄λ λΉμ’ μ μ΄λ¦κ³Ό ꡬλ³νκ³ νμ¬ μΈμ€ν΄μ€νμ λ©€λ²μΈμ§ λλ μ μ μλ νΉμνμ λ©€λ²μΈμ§ νλ¨νκΈ° μν¨μ λλ€. μ΄ μ‘°νλ₯Ό ν΅ν΄ μ»μ μ 보λ μ€λ₯ κ°μ§μ μ¬μ©λ μ μμΌλ©°, μλλ₯Ό μ°Έμ‘°νμμμ€.
μ’ μ νμ
λ€μ μ νλ€μ dependent types μ λλ€:
- ν νλ¦Ώ λ§€κ°λ³μ
- μλ €μ§μ§ μμ νΉμνμ λ©€λ² (μλ μ°Έμ‘°)
- μλ €μ§μ§ μμ νΉμνμ μ’ μ λ©€λ²μΈ μ€μ²© ν΄λμ€/μ΄κ±°ν (μλ μ°Έμ‘°)
- μ’ μ νμ μ cv νμ λ²μ
- μ’ μ νμ μΌλ‘ ꡬμ±λ λ³΅ν© νμ
- μμ νμ μ΄ μ’ μμ μ΄κ±°λ κ²½κ³(μλ κ²½μ°)κ° κ°-μ’ μμ μΈ λ°°μ΄ νμ
|
(since C++11) |
- μμΈ λͺ μΈκ° κ°μ μμ‘΄μ μΈ ν¨μ νμ
- λ€μ μ€ νλμΈ template-id
-
- ν νλ¦Ώ μ΄λ¦μ΄ ν νλ¦Ώ λ§€κ°λ³μμΈ κ²½μ°, λλ
- ν νλ¦Ώ μΈμ μ€ νλκ° type-dependentμ΄κ±°λ value-dependentμΈ κ²½μ° , λλ pack expansionμΈ κ²½μ° (C++11λΆν°) (ν νλ¦Ώ-idκ° μΈμ λͺ©λ‘ μμ΄ μ¬μ©λλ κ²½μ°μλ, μ¦ injected-class-name μΌλ‘ μ¬μ©λλ κ²½μ°μλ μ μ©λ¨)
νμ μμ‘΄μ ννμμ μ μ©λ decltype μ κ²°κ³Όλ κ³ μ ν μμ‘΄ νμ μ λλ€. λ κ°μ μ΄λ¬ν κ²°κ³Όλ ν΄λΉ ννμλ€μ΄ λλ±ν κ²½μ°μλ§ λμΌν νμ μ μ°Έμ‘°ν©λλ€. |
(C++11λΆν°) |
νμ μμ‘΄μ μμ ννμμ μ μ©λ pack indexing specifierλ κ³ μ ν μμ‘΄ νμ μ λλ€. λ κ°μ μ΄λ¬ν pack indexing specifierλ ν΄λΉ μμ ννμλ€μ΄ λλ±ν κ²½μ°μλ§ λμΌν νμ μ μ°Έμ‘°ν©λλ€. κ·Έλ μ§ μμ κ²½μ°, λ κ°μ μ΄λ¬ν pack indexing specifierλ ν΄λΉ μΈλ±μ€λ€μ΄ λμΌν κ°μ κ°μ§ λλ§ λμΌν νμ μ μ°Έμ‘°ν©λλ€. |
(since C++26) |
μ°Έκ³ : νμ¬ μΈμ€ν΄μ€νμ typedef λ©€λ²λ κ·Έκ²μ΄ μ°Έμ‘°νλ νμ μ΄ μ’ μμ μΌ λμλ§ μ’ μμ μ λλ€.
νμ μ’ μ ννμ
λ€μ ννμλ€μ type-dependent μ λλ€:
- μ΄λ€ νμ ννμμ΄λΌλ νμ μ’ μ ννμμΈ ννμ
- this , ν΄λμ€κ° μ’ μ νμ μΈ κ²½μ°
- μλ³μ ννμ μΌμ concept-id κ° μλκ³ (C++20λΆν°)
-
- μ΄λ¦ μ‘°ν(name lookup)κ° νλ μ΄μμ μ’ μ μ μΈ(dependent declaration)μ μ°Ύλ μλ³μλ₯Ό ν¬ν¨νλ κ²½μ°
- μ’ μμ μΈ template-id λ₯Ό ν¬ν¨νλ κ²½μ°
|
(C++11λΆν°) |
-
- μ’ μ νμ μΌλ‘μ λ³ν ν¨μ μ΄λ¦μ ν¬ν¨ν¨
- μλ €μ§μ§ μμ νΉμνμ λ©€λ²μΈ μ€μ²© μ΄λ¦ μ§μ μ λλ νμ λ μλ³μ λ₯Ό ν¬ν¨ν¨
- νμ¬ μΈμ€ν΄μ€νμ μ’ μ λ©€λ²λ‘μ "μλ €μ§μ§ μμ κ²½κ³μ λ°°μ΄" νμ μΈ μ μ λ°μ΄ν° λ©€λ²λ₯Ό μ§μΉν¨
|
(C++14λΆν°) |
|
(C++17λΆν°) |
|
(C++26λΆν°) |
- μ’ μ νμ μΌλ‘μ any cast ννμ
- new ννμ μ΄ μ’ μ νμ μ κ°μ²΄λ₯Ό μμ±νλ κ²½μ°
- νμ¬ μΈμ€ν΄μ€μ λ©€λ²λ₯Ό μ°Έμ‘°νλ λ©€λ² μ κ·Ό ννμμΌλ‘ ν΄λΉ λ©€λ²μ νμ μ΄ μ’ μμ μΈ κ²½μ°
- μλ €μ§μ§ μμ νΉμνμ λ©€λ²λ₯Ό μ°Έμ‘°νλ λ©€λ² μ κ·Ό ννμ
| (C++17λΆν°) |
|
(C++26λΆν°) |
λ€μ ννμλ€μ ν΄λΉ ννμλ€μ νμ μ΄ λ μ μκΈ° λλ¬Έμ μ λ νμ μμ‘΄μ μ΄μ§ μμ΅λλ€:
| (C++11λΆν°) |
| (C++20λΆν°) |
κ° μ’ μ ννμ
λ€μ ννμλ€μ value-dependent μ λλ€:
- μμ ννμμ΄ νμν λ¬Έλ§₯μμ μ¬μ©λλ©°, κ·Έ μ΄λ€ νμ ννμλ κ°μ μμ‘΄μ μΈ ννμ
- λ€μ 쑰건 μ€ νλλ₯Ό λ§μ‘±νλ μλ³μ ννμ :
|
(C++20λΆν°) |
-
- μ΄λ νμ μ μμ‘΄μ μ λλ€.
- μ΄λ μμ ν νλ¦Ώ λ§€κ°λ³μμ μ΄λ¦μ λλ€.
- μ΄λ νμ¬ μΈμ€ν΄μ€νμ μμ‘΄μ λ©€λ²μ΄λ©° μ΄κΈ°νλμ§ μμ μ μ λ°μ΄ν° λ©€λ²μ μ΄λ¦μ λλ€.
- μ΄λ νμ¬ μΈμ€ν΄μ€νμ μμ‘΄μ λ©€λ²μΈ μ μ λ©€λ² ν¨μμ μ΄λ¦μ λλ€.
- μ΄λ κ° μμ‘΄μ ννμμΌλ‘λΆν° μ΄κΈ°νλ μ μ λλ μ΄κ±°ν (C++11κΉμ§) 리ν°λ΄ (C++11 μ΄ν) νμ μ μμμ λλ€.
- νΌμ°μ°μκ° νμ μ’ μ ννμμΈ λ€μ ννμλ€:
| (C++11 μ΄ν) |
- νΌμ°μ°μκ° μ’ μ νμ μλ³μμΈ λ€μ ννμλ€:
- λμ μ νμ΄ μ’ μμ μ΄κ±°λ νΌμ°μ°μκ° μ ν μ’ μ ννμμΈ λ€μ ννμλ€:
- ν¨μ μ€νμΌ μΊμ€νΈ λμ νμ μ΄ μ’ μμ μ΄κ±°λ κ° μ’ μ ννμμ΄ κ΄νΈλ‘ λλ¬μΈμΈ ννμ λλ μ€κ΄νΈ (C++11λΆν°)
|
(C++11λΆν°) |
| (C++17λΆν°) |
- μΈμκ° νμ¬ μΈμ€ν΄μ€μ μ’ μ λ©€λ²λ₯Ό λͺ λͺ νλ νμ λ μλ³μ μΈ μ£Όμ μ°μ°μ ννμ
- μΈμκ° ν΅μ¬ μμ ννμ μΌλ‘ νκ°λ λ μ μ λλ μ€λ λ μ μ₯ κΈ°κ° (C++11λΆν°) μ κ°μ§ κ°μ²΄μ΄κ±°λ λ©€λ² ν¨μμΈ ν νλ¦Ώλ μν°ν° λ₯Ό μ°Έμ‘°νλ λͺ¨λ ννμμΈ μ£Όμ μ°μ°μ ννμ
μ’ μ μ΄λ¦
|
μ΄ μΉμ
μ λΆμμ ν©λλ€
μ΄μ : λλ½λ [temp.dep]μ λμ λΆ (μλ³μ ννμ λ€μ κ΄νΈλ‘ λλ¬μΈμΈ λͺ©λ‘... |
|
μ΄ μΉμ
μ λΆμμ ν©λλ€
μ΄μ : λ λͺ ννκ²(λλ μ μ΄λ λ μνμ μΌλ‘) μ¬κ΅¬μ±ν΄μΌ νλ©°, λμμ CWG issue 591 μ μ μ©ν΄μΌ ν¨ |
νμ¬ μΈμ€ν΄μ€ν
ν΄λμ€ ν νλ¦Ώ μ μ λ΄λΆ(λ©€λ² ν¨μμ μ€μ²© ν΄λμ€ ν¬ν¨)μμ μΌλΆ μ΄λ¦μ νμ¬ μΈμ€ν΄μ€ν λ₯Ό μ°Έμ‘°νλ κ²μΌλ‘ μΆλ‘ λ μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ νΉμ μ€λ₯λ€μ μΈμ€ν΄μ€ν μμ μ΄ μλ μ μ μμ μ κ°μ§ν μ μμΌλ©°, μλμμ μ€λͺ νλ μ’ μ μ΄λ¦μ λν typename κ³Ό template λͺ μμ μꡬμ¬νμ μ κ±°ν©λλ€.
νμ¬ μΈμ€ν΄μ€νλ₯Ό μ°Έμ‘°ν μ μλ μ΄λ¦μ λ€μκ³Ό κ°μ΅λλ€:
-
ν΄λμ€ ν
νλ¦Ώ, ν΄λμ€ ν
νλ¦Ώμ μ€μ²© ν΄λμ€, ν΄λμ€ ν
νλ¦Ώμ λ©€λ², λλ ν΄λμ€ ν
νλ¦Ώμ μ€μ²© ν΄λμ€ λ©€λ² μ μ λ΄μμ:
- ν΄λμ€ ν νλ¦Ώ λλ μ€μ²© ν΄λμ€μ μ£Όμ λ ν΄λμ€ μ΄λ¦(injected-class-name)
-
κΈ°λ³Έ ν΄λμ€ ν
νλ¦Ώ(primary class template) λλ κΈ°λ³Έ ν΄λμ€ ν
νλ¦Ώ λ©€λ² μ μ λ΄μμ:
- κΈ°λ³Έ ν νλ¦Ώμ λν ν νλ¦Ώ μΈμ λͺ©λ‘μ΄ λ€λ°λ₯΄λ ν΄λμ€ ν νλ¦Ώ μ΄λ¦ (λλ μ΄μ μμνλ λ³μΉ ν νλ¦Ώ νΉμν). κ° μΈμλ ν΄λΉ λ§€κ°λ³μμ λλ±(equivalent)ν΄μΌ ν¨
-
ν΄λμ€ ν
νλ¦Ώμ μ€μ²© ν΄λμ€ μ μ λ΄μμ:
- νμ¬ μΈμ€ν΄μ€(current instantiation)μ λ©€λ²λ‘ μ¬μ©λλ μ€μ²© ν΄λμ€ μ΄λ¦
-
ν΄λμ€ ν
νλ¦Ώ λΆλΆ νΉμν(class template partial specialization) λλ ν΄λμ€ ν
νλ¦Ώ λΆλΆ νΉμν λ©€λ² μ μ λ΄μμ:
- λΆλΆ νΉμνμ λν ν νλ¦Ώ μΈμ λͺ©λ‘μ΄ λ€λ°λ₯΄λ ν΄λμ€ ν νλ¦Ώ μ΄λ¦. κ° μΈμλ ν΄λΉ λ§€κ°λ³μμ λλ±ν΄μΌ ν¨
-
ν
νλ¦Ώνλ ν¨μ(templated function)
μ μ λ΄μμ:
- μ§μ ν΄λμ€(local class) μ μ΄λ¦
ν νλ¦Ώ μΈμλ λ€μκ³Ό κ°μ κ²½μ° ν νλ¦Ώ λ§€κ°λ³μμ λλ±ν©λλ€
- νμ λ§€κ°λ³μμ κ²½μ°, ν νλ¦Ώ μΈμλ ν νλ¦Ώ λ§€κ°λ³μμ λμΌν νμ μ λνλ λλ€.
- μμ λ§€κ°λ³μμ κ²½μ°, ν νλ¦Ώ μΈμλ ν νλ¦Ώ λ§€κ°λ³μμ λλ±ν λ³μλ₯Ό μ§μΉνλ μλ³μμ λλ€. λ³μλ λ€μ 쑰건μμ ν νλ¦Ώ λ§€κ°λ³μμ λλ±ν©λλ€:
-
- ν νλ¦Ώ λ§€κ°λ³μμ λμΌν νμ μ κ°μ§λ©°(cv νμ μλ 무μ)
- ν΄λΉ μ΄κΈ°νμκ° ν νλ¦Ώ λ§€κ°λ³μμ μ΄λ¦μΈ λ¨μΌ μλ³μλ‘ κ΅¬μ±λκ±°λ, μ¬κ·μ μΌλ‘ κ·Έλ¬ν λ³μλ‘ κ΅¬μ±λλ κ²½μ°
template<class T> class A { A* p1; // Aλ νμ¬ μΈμ€ν΄μ€νμ λλ€ A<T>* p2; // A<T>λ νμ¬ μΈμ€ν΄μ€νμ λλ€ ::A<T>* p4; //Β ::A<T>λ νμ¬ μΈμ€ν΄μ€νμ λλ€ A<T*> p3; // A<T*>λ νμ¬ μΈμ€ν΄μ€νκ° μλλλ€ class B { B* p1; // Bλ νμ¬ μΈμ€ν΄μ€νμ λλ€ A<T>::B* p2; // A<T>::Bλ νμ¬ μΈμ€ν΄μ€νμ λλ€ typename A<T*>::B* p3; // A<T*>::Bλ νμ¬ μΈμ€ν΄μ€νκ° μλλλ€ }; }; template<class T> class A<T*> { A<T*>* p1; // A<T*>λ νμ¬ μΈμ€ν΄μ€νμ λλ€ A<T>* p2; // A<T>λ νμ¬ μΈμ€ν΄μ€νκ° μλλλ€ }; template<int I> struct B { static const int my_I = I; static const int my_I2 = I + 0; static const int my_I3 = my_I; static const long my_I4 = I; static const int my_I5 = (I); B<my_I>* b1; // B<my_I>λ νμ¬ μΈμ€ν΄μ€νμ λλ€: // my_Iλ Iμ λμΌν νμ μ κ°μ§λ©°, // μ€μ§ Iλ‘λ§ μ΄κΈ°νλ©λλ€ B<my_I2>* b2; // B<my_I2>λ νμ¬ μΈμ€ν΄μ€νκ° μλλλ€: // I + 0μ λ¨μΌ μλ³μκ° μλλλ€ B<my_I3>* b3; // B<my_I3>λ νμ¬ μΈμ€ν΄μ€νμ λλ€: // my_I3λ Iμ λμΌν νμ μ κ°μ§λ©°, // μ€μ§ my_I(Iμ λλ±ν¨)λ‘λ§ μ΄κΈ°νλ©λλ€ B<my_I4>* b4; // B<my_I4>λ νμ¬ μΈμ€ν΄μ€νκ° μλλλ€: // my_I4μ νμ (long)μ΄ Iμ νμ (int)κ³Ό λμΌνμ§ μμ΅λλ€ B<my_I5>* b5; // B<my_I5>λ νμ¬ μΈμ€ν΄μ€νκ° μλλλ€: // (I)λ λ¨μΌ μλ³μκ° μλλλ€ };
μ€μ²© ν΄λμ€κ° μμ μ λλ¬μΌ ν΄λμ€ ν νλ¦Ώμμ νμλ κ²½μ° κΈ°λ³Έ ν΄λμ€κ° νμ¬ μΈμ€ν΄μ€ν(current instantiation)κ° λ μ μμμ μ μνμμμ€. μ’ μ νμ μ΄μ§λ§ νμ¬ μΈμ€ν΄μ€νκ° μλ κΈ°λ³Έ ν΄λμ€λ μ’ μ κΈ°λ³Έ ν΄λμ€(dependent base classes) μ λλ€:
template<class T> struct A { typedef int M; struct B { typedef void M; struct C; }; }; template<class T> struct A<T>::B::C : A<T> { M m; // μ μ, A<T>::M };
μ΄λ¦μ λ€μκ³Ό κ°μ κ²½μ° νμ¬ μΈμ€ν΄μ€νμ λ©€λ²λ‘ λΆλ₯λ©λλ€
- νμ¬ μΈμ€ν΄μ€ν λλ κ·Έ λΉμμ‘΄μ κΈ°μ μμ λΉνμ μ΄λ¦ κ²μ μΌλ‘ λ°κ²¬λ λΉνμ μ΄λ¦
-
νμ λ μ΄λ¦
(λ¨, νμ μ(
::μ μΌμͺ½μ μμΉν μ΄λ¦)κ° νμ¬ μΈμ€ν΄μ€νλ₯Ό μ§μΉνκ³ , κ²μμ΄ νμ¬ μΈμ€ν΄μ€ν λλ κ·Έ λΉμμ‘΄μ κΈ°μ μμ μ΄λ¦μ λ°κ²¬νλ κ²½μ°) - ν΄λμ€ λ©€λ² μ κ·Ό ννμμμ μ¬μ©λ μ΄λ¦ ( x. y λλ xp - > y μμμ y ), λ¨ κ°μ²΄ ννμ( x λλ * xp )μ΄ νμ¬ μΈμ€ν΄μ€νμ΄κ³ , κ²μμ΄ νμ¬ μΈμ€ν΄μ€ν λλ κ·Έ λΉμμ‘΄μ κΈ°μ μμ μ΄λ¦μ λ°κ²¬νλ κ²½μ°
template<class T> class A { static const int i = 5; int n1[i]; // iλ νμ¬ μΈμ€ν΄μ€νμ λ©€λ²λ₯Ό μ°Έμ‘°ν¨ int n2[A::i]; // A::iλ νμ¬ μΈμ€ν΄μ€νμ λ©€λ²λ₯Ό μ°Έμ‘°ν¨ int n3[A<T>::i]; // A<T>::iλ νμ¬ μΈμ€ν΄μ€νμ λ©€λ²λ₯Ό μ°Έμ‘°ν¨ int f(); }; template<class T> int A<T>::f() { return i; // iλ νμ¬ μΈμ€ν΄μ€νμ λ©€λ²λ₯Ό μ°Έμ‘°ν¨ }
νμ¬ μΈμ€ν΄μ€νμ λ©€λ²λ μ’ μμ μΌ μλ μκ³ λΉμ’ μμ μΌ μλ μμ΅λλ€.
νμ¬ μΈμ€ν΄μ€νμ λ©€λ² μ‘°νκ° μΈμ€ν΄μ€ν μ§μ κ³Ό μ μ μ§μ μ¬μ΄μμ λ€λ₯Έ κ²°κ³Όλ₯Ό μ 곡νλ©΄, ν΄λΉ μ‘°νλ λͺ¨νΈν©λλ€. κ·Έλ¬λ λ©€λ² μ΄λ¦μ΄ μ¬μ©λ λ μλμΌλ‘ ν΄λμ€ λ©€λ² μ κ·Ό ννμμΌλ‘ λ³νλμ§ μμΌλ©°, λͺ μμ λ©€λ² μ κ·Ό ννμλ§μ΄ νμ¬ μΈμ€ν΄μ€νμ λ©€λ²λ₯Ό λνλΈλ€λ μ μ μ μνμμμ€:
struct A { int m; }; struct B { int m; }; template<typename T> struct C : A, T { int f() { return this->m; } // ν νλ¦Ώ μ μ 컨ν μ€νΈμμ A::mμ μ°Ύμ int g() { return m; } // ν νλ¦Ώ μ μ 컨ν μ€νΈμμ A::mμ μ°Ύμ }; template int C<B>::f(); // μ€λ₯: A::mκ³Ό B::mμ λͺ¨λ μ°Ύμ template int C<B>::g(); // OK: ν΄λμ€ λ©€λ² μ κ·Ό ꡬ문μΌλ‘μ λ³νμ // ν νλ¦Ώ μ μ 컨ν μ€νΈμμ λ°μνμ§ μμ
μλ €μ§μ§ μμ νΉμν
ν νλ¦Ώ μ μ λ΄μμ νΉμ μ΄λ¦λ€μ unknown specialization μ μνλ κ²μΌλ‘ μΆλ‘ λ©λλ€, νΉν,
-
νμ λ μ΄λ¦
(
::μ μΌμͺ½μ λνλλ μ΄λ¦ μ€ νμ¬ μΈμ€ν΄μ€μ λ©€λ²κ° μλ μ’ μ νμ μ΄ μλ κ²½μ°) - νμ μκ° νμ¬ μΈμ€ν΄μ€μ΄κ³ , νμ¬ μΈμ€ν΄μ€ λλ λΉμ’ μ κΈ°λ³Έ ν΄λμ€μμ μ΄λ¦μ μ°Ύμ μ μμΌλ©° μ’ μ κΈ°λ³Έ ν΄λμ€κ° μ‘΄μ¬νλ νμ λ μ΄λ¦
- ν΄λμ€ λ©€λ² μ κ·Ό ννμμ λ©€λ² μ΄λ¦ ( x. y λλ xp - > y μμ y ), κ°μ²΄ ννμμ νμ ( x λλ * xp )μ΄ μ’ μ νμ μ΄κ³ νμ¬ μΈμ€ν΄μ€κ° μλ κ²½μ°
- ν΄λμ€ λ©€λ² μ κ·Ό ννμμ λ©€λ² μ΄λ¦ ( x. y λλ xp - > y μμ y ), κ°μ²΄ ννμμ νμ ( x λλ * xp )μ΄ νμ¬ μΈμ€ν΄μ€μ΄κ³ , νμ¬ μΈμ€ν΄μ€ λλ λΉμ’ μ κΈ°λ³Έ ν΄λμ€μμ μ΄λ¦μ μ°Ύμ μ μμΌλ©° μ’ μ κΈ°λ³Έ ν΄λμ€κ° μ‘΄μ¬νλ κ²½μ°
template<typename T> struct Base {}; template<typename T> struct Derived : Base<T> { void f() { // Derived<T>λ νμ¬ μΈμ€ν΄μ€νλ₯Ό μ°Έμ‘°ν¨ // νμ¬ μΈμ€ν΄μ€νμλ "unknown_type"μ΄ μ‘΄μ¬νμ§ μμ // κ·Έλ¬λ μ’ μ λ² μ΄μ€(Base<T>)κ° μ‘΄μ¬ν¨ // λ°λΌμ "unknown_type"μ μλ €μ§μ§ μμ νΉμνμ λ©€λ²μ typename Derived<T>::unknown_type z; } }; template<> struct Base<int> // μ΄ νΉμνμμ μ κ³΅ν¨ { typedef int unknown_type; };
μ΄ λΆλ₯λ₯Ό ν΅ν΄ ν
νλ¦Ώ μ μ μμ (μΈμ€ν΄μ€νκ° μλ)μ λ€μκ³Ό κ°μ μ€λ₯λ€μ κ²μΆν μ μμ΅λλ€:
- ν νλ¦Ώ μ μμμ νμ λ μ΄λ¦(qualified name) μ΄ νμ¬ μΈμ€ν΄μ€ν(current instantiation)λ₯Ό μ°Έμ‘°νλ νμ μλ₯Ό κ°μ§λ©°, ν΄λΉ μ΄λ¦μ΄ νμ¬ μΈμ€ν΄μ€νμ λ©€λ²λ μλκ³ μ μ μλ νΉμν(unknown specialization)μ λ©€λ²λ μλ κ²½μ°, ν νλ¦Ώμ΄ μΈμ€ν΄μ€νλμ§ μλλΌλ νλ‘κ·Έλ¨μ νμ μ€λ₯(ill-formed)μ λλ€ (μ§λ¨ λ©μμ§ μμ).
template<class T> class A { typedef int type; void f() { A<T>::type i; // OK: "type"λ νμ¬ μΈμ€ν΄μ€νμ λ©€λ²μ λλ€ typename A<T>::other j; // μ€λ₯: // "other"λ νμ¬ μΈμ€ν΄μ€νμ λ©€λ²κ° μλλ©° // μλ €μ§μ§ μμ νΉμνμ λ©€λ²λ μλλλ€ // μλνλ©΄ A<T> (νμ¬ μΈμ€ν΄μ€νλ₯Ό μ§μΉνλ)λ // "other"κ° μ¨μ μ μλ μμ‘΄μ κΈ°μ ν΄λμ€κ° μκΈ° λλ¬Έμ λλ€ } };
- ν νλ¦Ώ μ μμμ κ°μ²΄ ννμμ΄ νμ¬ μΈμ€ν΄μ€νμ΄μ§λ§, ν΄λΉ μ΄λ¦μ΄ νμ¬ μΈμ€ν΄μ€νμ λ©€λ²λ μλκ³ μ μ μλ νΉμνμ λ©€λ²λ μλ λ©€λ² μ κ·Ό ννμμ΄ μμ κ²½μ°, ν νλ¦Ώμ΄ μΈμ€ν΄μ€νλμ§ μλλΌλ νλ‘κ·Έλ¨μ ill-formedμ λλ€.
μλ €μ§μ§ μμ νΉμνμ λ©€λ²λ νμ μ’ μμ μ΄λ©°, λͺ¨λ μ’ μ μ΄λ¦κ³Ό λ§μ°¬κ°μ§λ‘ μΈμ€ν΄μ€ν μ§μ μμ μ‘°νλκ³ λ°μΈλ©λ©λλ€ (μ μ°Έμ‘°)
μ’ μ μ΄λ¦μ λν typename λͺ μμ
ν νλ¦Ώμ μ μΈ λλ μ μ(λ³μΉ ν νλ¦Ώ ν¬ν¨)μμ, νμ¬ μΈμ€ν΄μ€νμ λ©€λ²κ° μλκ³ ν νλ¦Ώ λ§€κ°λ³μμ μ’ μλ μ΄λ¦μ, typename ν€μλλ₯Ό μ¬μ©νκ±°λ typedef μ μΈμΌλ‘ νμ μ΄λ¦μΌλ‘ μ΄λ―Έ ν립λμκ±°λ κΈ°λ³Έ ν΄λμ€μ μ΄λ¦μ μ§μ νλ λ° μ¬μ©λλ κ²½μ°μ κ°μ κ²½μ°λ₯Ό μ μΈνκ³ λ νμ μΌλ‘ κ°μ£Όλμ§ μμ΅λλ€.
#include <iostream> #include <vector> int p = 1; template<typename T> void foo(const std::vector<T> &v) { // std::vector<T>::const_iteratorλ μ’ μ μ΄λ¦μ λλ€, typename std::vector<T>::const_iterator it = v.begin(); // "typename" μμ΄λ λ€μμ νμ μ’ μ λ°μ΄ν° λ©€λ² "const_iterator"μ // μ΄λ€ λ³μ "p"μ κ³±μ μΌλ‘ νμ±λ©λλ€. μ΄ μμ μμ μ μ "p"κ° λ³΄μ΄λ―λ‘ // μ΄ ν νλ¦Ώ μ μλ μ»΄νμΌλ©λλ€. std::vector<T>::const_iterator* p; typedef typename std::vector<T>::const_iterator iter_t; iter_t * p2; // "iter_t"λ μ’ μ μ΄λ¦μ΄μ§λ§ νμ μ΄λ¦μΌλ‘ μλ €μ Έ μμ΅λλ€ } template<typename T> struct S { typedef int value_t; // νμ¬ μΈμ€ν΄μ€μ λ©€λ² void f() { S<T>::value_t n{}; // S<T>λ μ’ μμ μ΄μ§λ§ "typename"μ΄ νμνμ§ μμ std::cout << n << '\n'; } }; int main() { std::vector<int> v; foo(v); // ν νλ¦Ώ μΈμ€ν΄μ€ν μ€ν¨: std::vector<int> νμ μ // "const_iterator"λΌλ λ©€λ² λ³μκ° μ‘΄μ¬νμ§ μμ S<int>().f(); }
ν€μλ typename λ νμ λ μ΄λ¦ μμμλ§ μ΄λ° λ°©μμΌλ‘ μ¬μ©λ μ μμ΅λλ€ (μ: T :: x ), νμ§λ§ μ΄λ¦μ΄ λ°λμ μ’ μμ μΌ νμλ μμ΅λλ€.
μΌλ°μ μΈ νμ μ΄λ¦ μ‘°ν κ° typename μΌλ‘ μ λμ¬λ μλ³μμ μ¬μ©λ©λλ€. μμΈ νμ μ§μ μ μ κ²½μ°μ λ¬λ¦¬, νμ μκ° μλλΌλ μ‘°ν κ·μΉμ λ³κ²½λμ§ μμ΅λλ€:
struct A // Aλ μ€μ²© λ³μ Xμ μ€μ²© νμ struct Xλ₯Ό κ°μ§ { struct X {}; int X; }; struct B { struct X {}; // Bλ μ€μ²© νμ struct Xλ₯Ό κ°μ§ }; template<class T> void f(T t) { typename T::X x; } void foo() { A a; B b; f(b); // OK: f<B>λ₯Ό μΈμ€ν΄μ€νν¨, T::Xλ B::Xλ₯Ό μ°Έμ‘° f(a); // μ€λ₯: f<A>λ₯Ό μΈμ€ν΄μ€νν μ μμ: // A::Xμ λν νμ μ΄λ¦ μ‘°νκ° λ°μ΄ν° λ©€λ²λ₯Ό μ°ΎκΈ° λλ¬Έ }
ν€μλ typename λ ν νλ¦Ώ μΈλΆμμλ μ¬μ©ν μ μμ΅λλ€.
#include <vector> int main() { // λ λ€ OK (CWG 382 ν΄κ²° μ΄ν) typedef typename std::vector<int>::const_iterator iter_t; typename std::vector<int> v; }
|
μ΄λ€ λ¬Έλ§₯μμλ μ€μ§ νμ μ΄λ¦λ§ μ ν¨νκ² λνλ μ μμ΅λλ€. μ΄λ¬ν λ¬Έλ§₯μμλ μ’ μμ νμ μ΄λ¦(dependent qualified name)μ΄ νμ μ μ§μΉνλ κ²μΌλ‘ κ°μ£Όλλ©° typename μ΄ νμνμ§ μμ΅λλ€:
|
(C++20λΆν°) |
μ’ μ μ΄λ¦μ λν template λͺ¨νΈμ± μ κ±°μ
λ§μ°¬κ°μ§λ‘, ν νλ¦Ώ μ μμμ νμ¬ μΈμ€ν΄μ€νμ λ©€λ²κ° μλ μ’ μ μ΄λ¦μ λΆλͺ ν μ§μ νλ ν€μλ template λ₯Ό μ¬μ©νκ±°λ μ΄λ―Έ ν νλ¦Ώ μ΄λ¦μΌλ‘ ν립λμ§ μλ ν ν νλ¦Ώ μ΄λ¦μΌλ‘ κ°μ£Όλμ§ μμ΅λλ€:
template<typename T> struct S { template<typename U> void foo() {} }; template<typename T> void bar() { S<T> s; s.foo<T>(); // μ€λ₯: <κ° less than μ°μ°μλ‘ νμ±λ¨ s.template foo<T>(); // μ μ }
ν€μλ template λ μ€μ§ μ°μ°μ :: (λ²μ μ§μ ), - > (ν¬μΈν°λ₯Ό ν΅ν λ©€λ² μ κ·Ό), κ·Έλ¦¬κ³ . (λ©€λ² μ κ·Ό) λ€μμλ§ μ΄λ° λ°©μμΌλ‘ μ¬μ©λ μ μμ΅λλ€. λ€μμ λͺ¨λ μ ν¨ν μμλ€μ λλ€:
- T :: template foo < X > ( ) ;
- s. template foo < X > ( ) ;
- this - > template foo < X > ( ) ;
- typename T :: template iterator < int > :: value_type v ;
`, `
`, `
typename μ κ²½μ°μ λ§μ°¬κ°μ§λ‘, template μ λμ¬λ μ΄λ¦μ΄ μ’ μμ μ΄μ§ μκ±°λ μ¬μ©μ΄ ν νλ¦Ώ λ²μ λ΄μ λνλμ§ μλ κ²½μ°μλ νμ©λ©λλ€.
μΌμͺ½μ μ΄λ¦μ΄
::
λ€μμ€νμ΄μ€λ₯Ό μ°Έμ‘°νλλΌλ, ν
νλ¦Ώ λͺ
μμλ νμ©λ©λλ€:
template<typename> struct S {}; ::template S<void> q; // νμ©λμ§λ§ λΆνμν¨
|
ν νλ¦Ώ μ΄λ¦μ λν λΉνμ μ΄λ¦ κ²μ μ νΉλ³ κ·μΉμΌλ‘ μΈν΄, λΉμμ‘΄μ ν νλ¦Ώ μ΄λ¦μ΄ λ©€λ² μ κ·Ό ννμ( - > μ΄ν λλ . μ΄ν)μ λνλ λ, ννμμ λ¬Έλ§₯μμ μΌλ° κ²μμΌλ‘ λμΌν μ΄λ¦μ κ°μ§ ν΄λμ€ λλ λ³μΉ (C++11λΆν°) ν νλ¦Ώμ΄ λ°κ²¬λλ©΄ λͺ μμ(template)λ λΆνμν©λλ€. κ·Έλ¬λ ννμ λ¬Έλ§₯μμ κ²μλ ν νλ¦Ώμ΄ ν΄λμ€ λ¬Έλ§₯μμ κ²μλ ν νλ¦Ώκ³Ό λ€λ₯Ό κ²½μ° νλ‘κ·Έλ¨μ μλͺ»λ νμμ λλ€ (C++11κΉμ§) template<int> struct A { int value; }; template<class T> void f(T t) { t.A<0>::value; // Aμ μΌλ° κ²μμ΄ ν΄λμ€ ν νλ¦Ώμ μ°Ύμ. // A<0>::valueλ ν΄λμ€ A<0>μ λ©€λ²λ₯Ό μ§μΉ // t.A < 0; // μ€λ₯: "<"κ° ν νλ¦Ώ μΈμ λͺ©λ‘μ μμμΌλ‘ μ²λ¦¬λ¨ } |
(C++23κΉμ§) |
ν€μλ
κ²°ν¨ λ³΄κ³ μ
λ€μ λμ λ³κ²½ κ²°ν¨ λ³΄κ³ μλ μ΄μ μ κ²μλ C++ νμ€μ μκΈ μ μ©λμμ΅λλ€.
| DR | μ μ© λμ | κ²μλ λμ | μ¬λ°λ₯Έ λμ |
|---|---|---|---|
| CWG 206 | C++98 |
ν
νλ¦Ώμ΄ μ μλ μ§μ μμ λΆμμ νμ§λ§ μΈμ€ν΄μ€νκ° μνλλ μ§μ μμ
μμ ν νμ μ΄ λΉμμ‘΄μ μ΄λ¦μ μ¬μ©λ λ μλ§¨ν± μ μ½ μ‘°κ±΄μ΄ μ μ©λλ μμ μ΄ λͺ μλμ§ μμμ |
μ΄ κ²½μ° νλ‘κ·Έλ¨μ νμ μ€λ₯μ΄λ©°
μ§λ¨ λ©μμ§κ° νμνμ§ μμ |
| CWG 224 | C++98 |
μμ‘΄μ νμ
μ μ μκ° μ΄λ¦ μ‘°ν보λ€λ
μ΄λ¦μ ννμ κΈ°λ°νμ |
μ μ κ°μ λ¨ |
| CWG 382 | C++98 | typename λͺ μμλ ν νλ¦Ώ λ²μμμλ§ νμ©λ¨ |
ν
νλ¦Ώ μΈλΆμμλ
νμ©λ¨ |
| CWG 468 | C++98 | template λͺ μμλ ν νλ¦Ώ λ²μμμλ§ νμ©λ¨ |
ν
νλ¦Ώ μΈλΆμμλ
νμ©λ¨ |
| CWG 502 | C++98 | μ€μ²© μ΄κ±°νμ΄ μμ‘΄μ μΈμ§ μ¬λΆκ° λͺ μλμ§ μμμ | μ€μ²© ν΄λμ€μ λμΌνκ² μμ‘΄μ μ |
| CWG 1047 | C++98 | typeid ννμμ κ°-μμ‘΄μ μ΄μ§ μμμ |
νΌμ°μ°μκ° νμ
-μμ‘΄μ μ΄λ©΄
κ°-μμ‘΄μ μ |
| CWG 1160 | C++98 |
ν
νλ¦Ώμ λ©€λ² μ μ λ΄μμ κΈ°λ³Έ ν
νλ¦Ώ λλ λΆλΆ νΉμνμ μΌμΉνλ
ν νλ¦Ώ IDκ° λνλ λ μ΄λ¦μ΄ νμ¬ μΈμ€ν΄μ€λ₯Ό μ°Έμ‘°νλμ§ μ¬λΆκ° λͺ μλμ§ μμμ |
λͺ μλ¨ |
| CWG 1413 | C++98 |
μ΄κΈ°νλμ§ μμ μ μ λ°μ΄ν° λ©€λ², μ μ λ©€λ² ν¨μ λ° ν΄λμ€ ν
νλ¦Ώμ
λ©€λ² μ£Όμκ° κ°-μμ‘΄μ λͺ©λ‘μ ν¬ν¨λμ§ μμμ |
ν¬ν¨λ¨ |
| CWG 1471 | C++98 |
νμ¬ μΈμ€ν΄μ€μ λΉμμ‘΄μ κΈ°λ³Έ ν΄λμ€μ
μ€μ²© νμ μ΄ μμ‘΄μ μ΄μμ |
μμ‘΄μ μ΄μ§ μμ |
| CWG 1850 | C++98 |
μ μ 컨ν
μ€νΈμ μΈμ€ν΄μ€ν μ§μ μ¬μ΄μμ μλ―Έκ° λ³κ²½λ μ μλ
κ²½μ°μ λͺ©λ‘μ΄ λΆμμ νμ |
μμ νκ² λ§λ¦ |
| CWG 1929 | C++98 |
template
λͺ
μμκ° μΌμͺ½ μ΄λ¦μ΄ λ€μμ€νμ΄μ€λ₯Ό μ°Έμ‘°νλ
::
λ€μ μ¬ μ μλμ§ λͺ
ννμ§ μμμ
|
νμ©λ¨ |
| CWG 2066 | C++98 | this λ κ°-μμ‘΄μ μ΄μ§ μμμ | κ°-μμ‘΄μ μΌ μ μμ |
| CWG 2100 | C++98 |
ν΄λμ€ ν
νλ¦Ώμ μ μ λ°μ΄ν° λ©€λ² μ£Όμκ°
κ°-μμ‘΄μ λͺ©λ‘μ ν¬ν¨λμ§ μμμ |
ν¬ν¨λ¨ |
| CWG 2109 | C++98 | νμ -μμ‘΄μ μλ³μ ννμμ΄ κ°-μμ‘΄μ μ΄μ§ μμ μ μμμ | νμ κ°-μμ‘΄μ μ |
| CWG 2276 | C++98 |
μμΈ λͺ
μΈκ° κ°-μμ‘΄μ μΈ ν¨μ νμ
μ΄
μμ‘΄μ νμ μ΄ μλμμ |
μμ‘΄μ νμ μ |
| CWG 2307 | C++98 |
κ΄νΈλ‘ λ¬ΆμΈ μμ ν
νλ¦Ώ λ§€κ°λ³μκ° ν
νλ¦Ώ μΈμλ‘ μ¬μ©λ λ
ν΄λΉ ν νλ¦Ώ λ§€κ°λ³μμ λλ±νμ |
λ μ΄μ λλ±νμ§ μμ |
| CWG 2457 | C++11 |
ν¨μ λ§€κ°λ³μ ν©μ κ°μ§ ν¨μ νμ
μ΄
μμ‘΄μ νμ μ΄ μλμμ |
μμ‘΄μ νμ μ |
| CWG 2785 | C++20 | requires ννμμ΄ νμ -μμ‘΄μ μΌ μ μμμ | μ λ νμ -μμ‘΄μ μ΄μ§ μμ |
| CWG 2905 | C++11 |
noexcept
ννμμ νΌμ°μ°μκ° κ°-μμ‘΄μ μΌ λλ§
κ°-μμ‘΄μ μ΄μμ |
νΌμ°μ°μκ° ν
νλ¦Ώ λ§€κ°λ³μλ₯Ό
ν¬ν¨νλ©΄ κ°-μμ‘΄μ μ |
| CWG 2936 | C++98 |
ν
νλ¦Ώνλ ν¨μμ μ§μ ν΄λμ€ μ΄λ¦μ΄
νμ¬ μΈμ€ν΄μ€μ μΌλΆκ° μλμμ |
νμ¬ μΈμ€ν΄μ€μ μΌλΆμ |