Namespaces
Variants

Dependent names

From ko.cppreference.net
< cpp β€Ž | language
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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)은 ν…œν”Œλ¦Ώ μ •μ˜ μ‹œμ μ—μ„œ 쑰회되고 λ°”μΈλ”©λ©λ‹ˆλ‹€. 이 바인딩은 ν…œν”Œλ¦Ώ μΈμŠ€ν„΄μŠ€ν™” μ‹œμ μ— 더 λ‚˜μ€ λ§€μΉ˜κ°€ μ‘΄μž¬ν•˜λ”λΌλ„ μœ μ§€λ©λ‹ˆλ‹€:

#include <iostream>
void g(double) { std::cout << "g(double)\n"; }
template<class T>
struct S
{
    void f() const
    {
        g(1); // "g"λŠ” λΉ„μ˜μ‘΄μ  이름, ν˜„μž¬ 바인딩됨
    }
};
void g(int) { std::cout << "g(int)\n"; }
int main()
{
    g(1);  // g(int) 호좜
    S<int> s;
    s.f(); // g(double) 호좜
}

ν…œν”Œλ¦Ώ νŠΉμˆ˜ν™”μ˜ μ •μ˜ μ»¨ν…μŠ€νŠΈμ™€ μΈμŠ€ν„΄μŠ€ν™” 지점 μ‚¬μ΄μ—μ„œ λΉ„μ˜μ‘΄μ  이름(non-dependent name)의 μ˜λ―Έκ°€ λ³€κ²½λ˜λŠ” 경우, ν”„λ‘œκ·Έλž¨μ€ ν˜•μ‹ 였λ₯˜μ΄λ©° 진단은 ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ΄λŠ” λ‹€μŒκ³Ό 같은 μƒν™©μ—μ„œ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€:

  • λΉ„μ˜μ‘΄μ  이름에 μ‚¬μš©λœ νƒ€μž…μ΄ λΆˆμ™„μ „ν•œ νƒ€μž… 으둜 μ •μ˜ 지점에 μ‘΄μž¬ν•˜μ§€λ§Œ, μΈμŠ€ν„΄μŠ€ν™” μ§€μ μ—μ„œλŠ” μ™„μ „ν•œ νƒ€μž…μ΄ λ˜λŠ” 경우
  • ν…œν”Œλ¦Ώ μ •μ˜μ—μ„œ 이름을 μ‘°νšŒν•  λ•Œ using-declaration 을 μ°Ύμ•˜μ§€λ§Œ, ν•΄λ‹Ή using-declaration이 팩 ν™•μž₯μ΄μ—ˆκ³  ν•΄λ‹Ή 팩이 λΉ„μ–΄ μžˆμ–΄μ„œ μΈμŠ€ν„΄μŠ€ν™”μ—μ„œ ν•΄λ‹Ή λ²”μœ„μ˜ μ‘°νšŒκ°€ μ–΄λ–€ 선언도 μ°Ύμ§€ λͺ»ν•˜λŠ” 경우
(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 ν•œμ • 버전
  • 쒅속 νƒ€μž…μœΌλ‘œ κ΅¬μ„±λœ 볡합 νƒ€μž…
  • μš”μ†Œ νƒ€μž…μ΄ μ’…μ†μ μ΄κ±°λ‚˜ 경계(μžˆλŠ” 경우)κ°€ κ°’-쒅속적인 λ°°μ—΄ νƒ€μž…
  • ν•˜λ‚˜ μ΄μƒμ˜ ν•¨μˆ˜ parameter packs λ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ ν¬ν•¨ν•˜λŠ” ν•¨μˆ˜ νƒ€μž…
(since C++11)
  • μ˜ˆμ™Έ λͺ…μ„Έκ°€ 값에 의쑴적인 ν•¨μˆ˜ νƒ€μž…
  • λ‹€μŒ 쀑 ν•˜λ‚˜μΈ template-id
  • ν…œν”Œλ¦Ώ 이름이 ν…œν”Œλ¦Ώ λ§€κ°œλ³€μˆ˜μΈ 경우, λ˜λŠ”
  • ν…œν”Œλ¦Ώ 인자 쀑 ν•˜λ‚˜κ°€ type-dependentμ΄κ±°λ‚˜ value-dependent인 경우 , λ˜λŠ” pack expansion인 경우 (C++11λΆ€ν„°) (ν…œν”Œλ¦Ώ-idκ°€ 인자 λͺ©λ‘ 없이 μ‚¬μš©λ˜λŠ” κ²½μš°μ—λ„, 즉 injected-class-name 으둜 μ‚¬μš©λ˜λŠ” κ²½μš°μ—λ„ 적용됨)
  • νƒ€μž… 의쑴적 ν‘œν˜„μ‹μ— 적용된 decltype 의 κ²°κ³Ό

νƒ€μž… 의쑴적 ν‘œν˜„μ‹μ— 적용된 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 λ₯Ό ν¬ν•¨ν•˜λŠ” 경우
  • 특수 μ‹λ³„μž __func__ λ₯Ό 포함함 (λ§Œμ•½ μ–΄λ–€ λ‘˜λŸ¬μ‹ΈλŠ” ν•¨μˆ˜κ°€ ν…œν”Œλ¦Ώμ΄κ±°λ‚˜, 클래슀 ν…œν”Œλ¦Ώμ˜ λΉ„ν…œν”Œλ¦Ώ 멀버 , λ˜λŠ” μ œλ„€λ¦­ λžŒλ‹€μΈ 경우 (C++14λΆ€ν„°) )
(C++11λΆ€ν„°)
  • 쒅속 νƒ€μž…μœΌλ‘œμ˜ λ³€ν™˜ ν•¨μˆ˜ 이름을 포함함
  • μ•Œλ €μ§€μ§€ μ•Šμ€ νŠΉμˆ˜ν™”μ˜ 멀버인 쀑첩 이름 μ§€μ •μž λ˜λŠ” ν•œμ •λœ μ‹λ³„μž λ₯Ό 포함함
  • ν˜„μž¬ μΈμŠ€ν„΄μŠ€ν™”μ˜ 쒅속 λ©€λ²„λ‘œμ„œ "μ•Œλ €μ§€μ§€ μ•Šμ€ κ²½κ³„μ˜ λ°°μ—΄" νƒ€μž…μΈ 정적 데이터 멀버λ₯Ό 지칭함
  • 이름 검색(name lookup)이 ν˜„μž¬ μΈμŠ€ν„΄μŠ€ν™”μ˜ 멀버 ν•¨μˆ˜ 선언을 ν•˜λ‚˜ 이상 μ°ΎλŠ” μ‹λ³„μžλ₯Ό ν¬ν•¨ν•˜λ©°, ν•΄λ‹Ή 선언은 λ°˜ν™˜ν˜• μΆ”λ‘  으둜 선언됨
(C++14λΆ€ν„°)
  • 이름 검색이 ν˜•μ‹-의쑴적인 μ΄ˆκΈ°ν™”μžλ₯Ό κ°€μ§„ κ΅¬μ‘°εŒ– 바인딩 μ„ μ–Έ 을 μ°ΎλŠ” μ‹λ³„μžλ₯Ό 포함함
  • 이름 검색이 자리 ν‘œμ‹œμž auto λ₯Ό ν¬ν•¨ν•˜λŠ” ν˜•μ‹μ„ κ°€μ§„ μƒμˆ˜ ν…œν”Œλ¦Ώ λ§€κ°œλ³€μˆ˜λ₯Ό μ°ΎλŠ” μ‹λ³„μžλ₯Ό 포함함
  • 이름 검색이 자리 ν‘œμ‹œμž ν˜•μ‹μ„ ν¬ν•¨ν•˜λŠ” ν˜•μ‹μœΌλ‘œ μ„ μ–Έλœ λ³€μˆ˜(예: auto 정적 데이터 멀버)λ₯Ό μ°ΎλŠ” μ‹λ³„μžλ₯Ό ν¬ν•¨ν•˜λ©°, μ΄ˆκΈ°ν™”μžκ°€ ν˜•μ‹-의쑴적인 경우
(C++17λΆ€ν„°)
  • 이름 검색이 νŒ¨ν‚Ή 을 μ°ΎλŠ” μ‹λ³„μžλ₯Ό 포함함
(C++26λΆ€ν„°)
  • 쒅속 νƒ€μž…μœΌλ‘œμ˜ any cast ν‘œν˜„μ‹
  • new ν‘œν˜„μ‹ 이 쒅속 νƒ€μž…μ˜ 객체λ₯Ό μƒμ„±ν•˜λŠ” 경우
  • ν˜„μž¬ μΈμŠ€ν„΄μŠ€μ˜ 멀버λ₯Ό μ°Έμ‘°ν•˜λŠ” 멀버 μ ‘κ·Ό ν‘œν˜„μ‹μœΌλ‘œ ν•΄λ‹Ή λ©€λ²„μ˜ νƒ€μž…μ΄ 쒅속적인 경우
  • μ•Œλ €μ§€μ§€ μ•Šμ€ νŠΉμˆ˜ν™”μ˜ 멀버λ₯Ό μ°Έμ‘°ν•˜λŠ” 멀버 μ ‘κ·Ό ν‘œν˜„μ‹
(C++17λΆ€ν„°)
  • pack indexing expression μ‹λ³„μž ν‘œν˜„μ‹μ΄ νƒ€μž… 의쑴적 ν‘œν˜„μ‹μΈ 경우
(C++26λΆ€ν„°)

λ‹€μŒ ν‘œν˜„μ‹λ“€μ€ ν•΄λ‹Ή ν‘œν˜„μ‹λ“€μ˜ νƒ€μž…μ΄ 될 수 μ—†κΈ° λ•Œλ¬Έμ— μ ˆλŒ€ νƒ€μž… μ˜μ‘΄μ μ΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€:

(C++11λΆ€ν„°)
(C++20λΆ€ν„°)

κ°’ 쒅속 ν‘œν˜„μ‹

λ‹€μŒ ν‘œν˜„μ‹λ“€μ€ value-dependent μž…λ‹ˆλ‹€:

  • μƒμˆ˜ ν‘œν˜„μ‹μ΄ ν•„μš”ν•œ λ¬Έλ§₯μ—μ„œ μ‚¬μš©λ˜λ©°, κ·Έ μ–΄λ–€ ν•˜μœ„ ν‘œν˜„μ‹λ„ 값에 의쑴적인 ν‘œν˜„μ‹
  • λ‹€μŒ 쑰건 쀑 ν•˜λ‚˜λ₯Ό λ§Œμ‘±ν•˜λŠ” μ‹λ³„μž ν‘œν˜„μ‹ :
  • 이것은 concept-id 이며 인수 쀑 ν•˜λ‚˜λΌλ„ μ’…μ†μ μž…λ‹ˆλ‹€.
(C++20λΆ€ν„°)
  • μ΄λŠ” νƒ€μž…μ— μ˜μ‘΄μ μž…λ‹ˆλ‹€.
  • μ΄λŠ” μƒμˆ˜ ν…œν”Œλ¦Ώ λ§€κ°œλ³€μˆ˜μ˜ μ΄λ¦„μž…λ‹ˆλ‹€.
  • μ΄λŠ” ν˜„μž¬ μΈμŠ€ν„΄μŠ€ν™”μ˜ 의쑴적 멀버이며 μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šμ€ 정적 데이터 λ©€λ²„μ˜ μ΄λ¦„μž…λ‹ˆλ‹€.
  • μ΄λŠ” ν˜„μž¬ μΈμŠ€ν„΄μŠ€ν™”μ˜ 의쑴적 멀버인 정적 멀버 ν•¨μˆ˜μ˜ μ΄λ¦„μž…λ‹ˆλ‹€.
  • μ΄λŠ” κ°’ 의쑴적 ν‘œν˜„μ‹μœΌλ‘œλΆ€ν„° μ΄ˆκΈ°ν™”λœ μ •μˆ˜ λ˜λŠ” μ—΄κ±°ν˜• (C++11κΉŒμ§€) λ¦¬ν„°λŸ΄ (C++11 이후) νƒ€μž…μ˜ μƒμˆ˜μž…λ‹ˆλ‹€.
  • ν”Όμ—°μ‚°μžκ°€ νƒ€μž… 쒅속 ν‘œν˜„μ‹μΈ λ‹€μŒ ν‘œν˜„μ‹λ“€:
(C++11 이후)
  • ν”Όμ—°μ‚°μžκ°€ 쒅속 νƒ€μž… μ‹λ³„μžμΈ λ‹€μŒ ν‘œν˜„μ‹λ“€:
  • λŒ€μƒ μœ ν˜•μ΄ μ’…μ†μ μ΄κ±°λ‚˜ ν”Όμ—°μ‚°μžκ°€ μœ ν˜• 쒅속 ν‘œν˜„μ‹μΈ λ‹€μŒ ν‘œν˜„μ‹λ“€:
  • ν•¨μˆ˜ μŠ€νƒ€μΌ 캐슀트 λŒ€μƒ νƒ€μž…μ΄ μ’…μ†μ μ΄κ±°λ‚˜ κ°’ 쒅속 ν‘œν˜„μ‹μ΄ κ΄„ν˜Έλ‘œ λ‘˜λŸ¬μ‹ΈμΈ ν‘œν˜„μ‹ λ˜λŠ” μ€‘κ΄„ν˜Έ (C++11λΆ€ν„°)
(C++11λΆ€ν„°)
(C++17λΆ€ν„°)
  • μΈμˆ˜κ°€ ν˜„μž¬ μΈμŠ€ν„΄μŠ€μ˜ 쒅속 멀버λ₯Ό λͺ…λͺ…ν•˜λŠ” ν•œμ •λœ μ‹λ³„μž 인 μ£Όμ†Œ μ—°μ‚°μž ν‘œν˜„μ‹
  • μΈμˆ˜κ°€ 핡심 μƒμˆ˜ ν‘œν˜„μ‹ 으둜 평가될 λ•Œ 정적 λ˜λŠ” μŠ€λ ˆλ“œ μ €μž₯ κΈ°κ°„ (C++11λΆ€ν„°) 을 κ°€μ§„ κ°μ²΄μ΄κ±°λ‚˜ 멀버 ν•¨μˆ˜μΈ ν…œν”Œλ¦Ώλœ μ—”ν‹°ν‹° λ₯Ό μ°Έμ‘°ν•˜λŠ” λͺ¨λ“  ν‘œν˜„μ‹μΈ μ£Όμ†Œ μ—°μ‚°μž ν‘œν˜„μ‹

쒅속 이름

ν˜„μž¬ μΈμŠ€ν„΄μŠ€ν™”

클래슀 ν…œν”Œλ¦Ώ μ •μ˜ λ‚΄λΆ€(멀버 ν•¨μˆ˜μ™€ 쀑첩 클래슀 포함)μ—μ„œ 일뢀 이름은 ν˜„μž¬ μΈμŠ€ν„΄μŠ€ν™” λ₯Ό μ°Έμ‘°ν•˜λŠ” κ²ƒμœΌλ‘œ 좔둠될 수 μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 νŠΉμ • 였λ₯˜λ“€μ„ μΈμŠ€ν„΄μŠ€ν™” μ‹œμ μ΄ μ•„λ‹Œ μ •μ˜ μ‹œμ μ— 감지할 수 있으며, μ•„λž˜μ—μ„œ μ„€λͺ…ν•˜λŠ” 쒅속 이름에 λŒ€ν•œ typename κ³Ό template λͺ…μ‹œμž μš”κ΅¬μ‚¬ν•­μ„ μ œκ±°ν•©λ‹ˆλ‹€.

ν˜„μž¬ μΈμŠ€ν„΄μŠ€ν™”λ₯Ό μ°Έμ‘°ν•  수 μžˆλŠ” 이름은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

  • 클래슀 ν…œν”Œλ¦Ώ, 클래슀 ν…œν”Œλ¦Ώμ˜ 쀑첩 클래슀, 클래슀 ν…œν”Œλ¦Ώμ˜ 멀버, λ˜λŠ” 클래슀 ν…œν”Œλ¦Ώμ˜ 쀑첩 클래슀 멀버 μ •μ˜ λ‚΄μ—μ„œ:
    • 클래슀 ν…œν”Œλ¦Ώ λ˜λŠ” 쀑첩 클래슀의 μ£Όμž…λœ 클래슀 이름(injected-class-name)
  • κΈ°λ³Έ 클래슀 ν…œν”Œλ¦Ώ(primary class template) λ˜λŠ” κΈ°λ³Έ 클래슀 ν…œν”Œλ¦Ώ 멀버 μ •μ˜ λ‚΄μ—μ„œ:
    • κΈ°λ³Έ ν…œν”Œλ¦Ώμ— λŒ€ν•œ ν…œν”Œλ¦Ώ 인자 λͺ©λ‘μ΄ λ’€λ”°λ₯΄λŠ” 클래슀 ν…œν”Œλ¦Ώ 이름 (λ˜λŠ” 이에 μƒμ‘ν•˜λŠ” 별칭 ν…œν”Œλ¦Ώ νŠΉμˆ˜ν™”). 각 μΈμžλŠ” ν•΄λ‹Ή λ§€κ°œλ³€μˆ˜μ™€ 동등(equivalent)ν•΄μ•Ό 함
  • 클래슀 ν…œν”Œλ¦Ώμ˜ 쀑첩 클래슀 μ •μ˜ λ‚΄μ—μ„œ:
    • ν˜„μž¬ μΈμŠ€ν„΄μŠ€(current instantiation)의 λ©€λ²„λ‘œ μ‚¬μš©λ˜λŠ” 쀑첩 클래슀 이름
  • 클래슀 ν…œν”Œλ¦Ώ λΆ€λΆ„ νŠΉμˆ˜ν™”(class template partial specialization) λ˜λŠ” 클래슀 ν…œν”Œλ¦Ώ λΆ€λΆ„ νŠΉμˆ˜ν™” 멀버 μ •μ˜ λ‚΄μ—μ„œ:
    • λΆ€λΆ„ νŠΉμˆ˜ν™”μ— λŒ€ν•œ ν…œν”Œλ¦Ώ 인자 λͺ©λ‘μ΄ λ’€λ”°λ₯΄λŠ” 클래슀 ν…œν”Œλ¦Ώ 이름. 각 μΈμžλŠ” ν•΄λ‹Ή λ§€κ°œλ³€μˆ˜μ™€ 동등해야 함
  • ν…œν”Œλ¦Ών™”λœ ν•¨μˆ˜(templated function) μ •μ˜ λ‚΄μ—μ„œ:

ν…œν”Œλ¦Ώ μΈμžλŠ” λ‹€μŒκ³Ό 같은 경우 ν…œν”Œλ¦Ώ λ§€κ°œλ³€μˆ˜μ™€ λ™λ“±ν•©λ‹ˆλ‹€

  • νƒ€μž… λ§€κ°œλ³€μˆ˜μ˜ 경우, ν…œν”Œλ¦Ώ μΈμžλŠ” ν…œν”Œλ¦Ώ λ§€κ°œλ³€μˆ˜μ™€ λ™μΌν•œ νƒ€μž…μ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
  • μƒμˆ˜ λ§€κ°œλ³€μˆ˜μ˜ 경우, ν…œν”Œλ¦Ώ μΈμžλŠ” ν…œν”Œλ¦Ώ λ§€κ°œλ³€μˆ˜μ™€ λ™λ“±ν•œ λ³€μˆ˜λ₯Ό μ§€μΉ­ν•˜λŠ” μ‹λ³„μžμž…λ‹ˆλ‹€. λ³€μˆ˜λŠ” λ‹€μŒ μ‘°κ±΄μ—μ„œ ν…œν”Œλ¦Ώ λ§€κ°œλ³€μˆ˜μ™€ λ™λ“±ν•©λ‹ˆλ‹€:
  • ν…œν”Œλ¦Ώ λ§€κ°œλ³€μˆ˜μ™€ λ™μΌν•œ νƒ€μž…μ„ κ°€μ§€λ©°(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 이 ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€:

  • λ‹€μŒμ˜ (μ΅œμƒμœ„) decl-specifier-seq μ—μ„œ μ„ μ–Έ μ§€μ •μž 둜 μ‚¬μš©λ˜λŠ” ν•œμ • 이름:
  • νƒ€μž… ID 에 λ‚˜νƒ€λ‚˜λŠ” ν•œμ • μ΄λ¦„μœΌλ‘œ, κ°€μž₯ μž‘μ€ λ‘˜λŸ¬μ‹ΈλŠ” νƒ€μž… IDκ°€ λ‹€μŒμΈ 경우:
(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 ;
**μ°Έκ³ :** 제곡된 μ›ΉνŽ˜μ΄μ§€ λ‚΄μš©μ€ C++ μ½”λ“œ 쑰각으둜 κ΅¬μ„±λ˜μ–΄ 있으며, μ§€μ‹œμ‚¬ν•­μ— 따라 λͺ¨λ“  HTML νƒœκ·Έμ™€ 속성, 그리고 ` `, `
`, `` νƒœκ·Έ λ‚΄μ˜ ν…μŠ€νŠΈ(이 경우 C++ μ½”λ“œ 전체)λ₯Ό λ²ˆμ—­ν•˜μ§€ μ•Šκ³  λ³΄μ‘΄ν–ˆμŠ΅λ‹ˆλ‹€. C++ κ΄€λ ¨ μš©μ–΄λ„ λ²ˆμ—­ν•˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ 원본 μ½”λ“œκ°€ κ·ΈλŒ€λ‘œ μœ μ§€λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

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κΉŒμ§€)

ν‚€μ›Œλ“œ

template , typename

결함 λ³΄κ³ μ„œ

λ‹€μŒ λ™μž‘ λ³€κ²½ 결함 λ³΄κ³ μ„œλŠ” 이전에 κ²Œμ‹œλœ 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 ν…œν”Œλ¦Ών™”λœ ν•¨μˆ˜μ˜ μ§€μ—­ 클래슀 이름이
ν˜„μž¬ μΈμŠ€ν„΄μŠ€μ˜ 일뢀가 μ•„λ‹ˆμ—ˆμŒ
ν˜„μž¬ μΈμŠ€ν„΄μŠ€μ˜ μΌλΆ€μž„