2013-08-06 2 views
0

코드베이스에 여러 "리소스"가 있습니다. 모두 클래스이며 하나의 클래스를 제외하고 동일한 인터페이스를 공유합니다. ShaderProgram은 단지 한 가지 방법 만 다르며 정점 파일과 프래그먼트 파일의 파일 이름에 두 개의 문자열이 필요합니다.템플릿 전문화로 해결할 수 있습니까?

두 개의 파일이 필요하고 다른 템플릿이 필요하기 때문에 쉐이더 1을 제외한 모든 리소스를 처리하는 ResourceManager라는 템플릿 클래스가 있습니다. 템플릿 전문화로이를 해결할 수 있습니까? 그것은 ResourceManager가 GetOrLoadFromFile (string, string) 버전이 아닌 버전 (version)을 볼 수 있어야합니다. 반면에 다른 버전은 반대로, (string)과 not (string, string)를 볼 수 있습니다. 또한 AttemptLoad도 치료가 필요합니다. 이 코드에 대한 솔루션을 만들려면 어떻게해야합니까? 템플릿 전문화를 한 번도 해보지 않았습니다.

답변

0

템플릿 뒤에있는 아이디어는 실행 시간 (예 : 컴파일 시간) 전에 유형을 알고 있다는 것입니다. 이것이 사실이라면, 당신이하려는 것은 템플릿을 사용하는 오버로드입니다. 따라서, 나는 컴파일시에 오버로딩하는 코드에 적응할 수있는 일반적인 코드를 작성한다.

코드를 두 번 쓰는 것을 피하기 위해 모든 일반적인 메서드는 기본 클래스에 넣어지고 파생 클래스에는 발산되는 메서드 만 전달됩니다.

#include <memory> 
#include <string> 
#include <iostream> 

using namespace std; 

class Base 
{ 
    // put common codes here 
}; 

template <typename ResType> 
class ResourceManager : public Base 
{ 
public: 
    unique_ptr<ResType> GetorLoad(const string &f) { cout << f << endl; return 0;} 
}; 

// Specilizing class ResourceManager for string type 
template <> 
class ResourceManager<string> : public Base 
{ 
public: 
    unique_ptr<string> GetorLoad(const string &f1, const string &f2) {cout << f1 << f2 << endl; return 0;} 
}; 

int main() 
{ 
    ResourceManager<int> i; 
    ResourceManager<string> s; 

    i.GetorLoad("int"); 
    s.GetorLoad("string", "string"); 
} 

ps. 이 예제를 컴파일하고 테스트하려면 gcc 또는 clang ++ 컴파일러에서 '--std = C++ 11'플래그를 사용해야합니다.

1

두 클래스가 모두 제어 할 수 있다면 다른 해결책을 제안 할 것입니다.

class LoadConfiguration 
{ 
    public: 
      std::string FirstFileName; 
}; 

class ExtendedLoadConfiguration : public LoadConfiguration 
{ 
    public: 
      std::string SecondFileName; 
}; 

당신이 다음 항상 LoadConfiguration과 함께 일할 수있는 각 AttemptLoad가 취할 수 있습니다 어디에서 왜

SmartPointer<ResType> AttemptLoad(const LoadConfiguration &p_loadConfiguration); 

처럼 뭔가에 AttempLoad 방법을 변경하지 마십시오 그가 필요로하는 것. 새로운 인수를 추가하는 것은 쉽고 동일한 서명을 가진 코드가 적기 때문에 템플릿 전문화 작업을 할 필요가 없습니다.

+0

이것은 좋은 생각입니다. 이렇게하는 것이 좋습니다. – EddieV223

+0

ResourceManager :: AttempLoad (const LoadConfiguration)를 호출하는 것이 가능하지 않습니까? 단일 문자열 클래스는 무엇입니까? 귀하의 모범을 막을 수있는 방법은 없습니다. – EddieV223

+0

AttempLoad는 올바른 유형의 LoadConfiguration에 대한 dynamic_cast를 수행하려고합니다. 예, 어떤 의미에서는 컴파일 시간 검사에서 런타임 검사로 이동하고 있습니다. 그러나 다른 의미에서 ExtendedLoadConfiguration 대신 LoadConfiguration을 전달하면 빈 두 번째 문자열을 전달하는 것과 똑같이 처리해야합니다 (가능한 경우 쉽게 처리해야 함). 나는 표준 및 확장 성 API의 이점과 편안함이이 문제보다 더 중요하다고 생각한다. – Vadim

0

그냥 모두 'GetOrLoadFromFile'기능을 구현 :

#include <string> 

struct R1 
{ 
    void load (const std::string &name) {} 
}; 

struct R2 
{ 
    void load (const std::string &name0, const std::string name1) {} 
}; 

template<typename R> 
struct M 
{ 
    R *get_or_load (const std::string &name) 
    { 
    R *p = new R(); 
    p->load (name); 
    return p; 
    } 

    R *get_or_load (const std::string &name0, 
        const std::string &name1) 
    { 
    R *p = new R(); 
    p->load (name0, name1); 
    return p; 
    } 
}; 


M<R1> m1; 

M<R2> m2; 


int 
main() 
{ 
    R1 *p0 = m1.get_or_load ("foo"); 
    // R1 *p1 = m2.get_or_load ("foo"); // error 
    R2 *q0 = m2.get_or_load ("foo", "bar"); 
    // R2 *q1 = m1.get_or_load ("foo", "bar"); // error 
} 

은 "잘못"멤버 함수는 인스턴스화되지 않습니다, 실제로 컴파일러는 진단과 함께 종료되는 경우에 호출로,이 아니라면.

관련 문제