2012-12-19 49 views
5

Ok, tôi đọc Xuyên khá một số “không thể suy ra mẫu lập luận” câu hỏi nhưng không ai có vẻ để phù hợp với trường hợp của tôi - hoặc tôi không hiểu câu trả lời ...Suy luận mẫu đối số cho mẫu lồng nhau không

one mà tôi cảm thấy đi đúng hướng, nhưng tôi đã không giải được giải pháp cho vấn đề của mình.

Các lột xuống mã trong phần đầu của tôi trông như thế này:

template<typename T> 
class TemplateProblem 
{ 
public: 
    // Do I really need this or did I miss something from the STL? 
    template<typename Tin, typename Tout> 
    struct UnaryFunction : public std::unary_function<Tin, Tout> 
    { 
     virtual Tout operator()(Tin input) = 0; 
    }; 

    template<typename Tin, typename Tout> 
    struct StaticCast : public UnaryFunction<Tin, Tout> 
    { 
     virtual Tout operator()(Tin input) 
     { 
      return static_cast<Tout>(input); 
     } 
    }; 

private: 
    T * const _data; 
    T const _bias; 

    template<typename Tin> 
    void Init(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias); 

public: 
    template<typename Tin> 
    TemplateProblem(Tin * data, int length, Tin bias = Tin()); 

    template<typename Tin> 
    TemplateProblem(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias = T()); 
}; 

template<typename T> 
template<typename Tin> 
void TemplateProblem<T>::Init(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias) 
{ 
    T mappedBias = mapper(bias); 
    for (int i = 0; i < length; i++) 
    { 
     _data[i] = data[i] + mappedBias; 
    } 
} 

template<typename T> 
template<typename Tin> 
TemplateProblem<T>::TemplateProblem(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias = T()) 
    : _data(new T[length]), _bias(bias) 
{ 
    Init(data, length, mapper, bias); 
} 

template<typename T> 
template<typename Tin> 
TemplateProblem<T>::TemplateProblem(Tin * data, int length, Tin bias = T()) 
    : _data(new T[length]), _bias(bias) 
{ 
    StaticCast<Tin, T> cast; 
    Init(data, length, cast, bias); 
} 

Tôi nhanh chóng nó như thế này:

unsigned char pixels[] = {23, 42, 65, 97}; 
TemplateProblem<int> tp(pixels, 4); 

Từ VS2012 tôi nhận được những tin nhắn này:

Error 1 error C2784: 'void TemplateProblem<T>::Init(Tin *,int,TemplateProblem<T>::UnaryFunction<Tin,T>,Tin)' : could not deduce template argument for 'TemplateProblem<T>::UnaryFunction<Tin,T>' from 'TemplateProblem<T>::StaticCast<Tin,Tout>' ...\templateproblem.h 62 1 TemplateProblem 
Error 2 error C2893: Failed to specialize function template 'void TemplateProblem<T>::Init(Tin *,int,TemplateProblem<T>::UnaryFunction<Tin,T>,Tin)' ...\templateproblem.h 62 1 TemplateProblem 

Các cũng xảy ra khi tôi di chuyển hai số struct ra khỏi số classthis answer gợi ý.

+1

Mã instantiation và thông báo lỗi hoàn toàn không liên quan. Lỗi nói về 'StaticCast ', nhưng bạn không có bất kỳ nơi nào trong mã instantiation của bạn. – Xeo

+0

http://liveworkspace.org/code/4psoUf$0 biên dịch tốt ... mã của bạn (trước khi sửa đổi) không thể kết hợp được. – ForEveR

+0

@Xeo: StaticCast được sử dụng 3 dòng từ phía dưới. – primfaktor

Trả lời

4

Lỗi trình biên dịch không phải là rất hữu ích trong việc chỉ ra vấn đề thực tế.

Vấn đề thực tế là bạn vượt qua UnaryFunction<Tin, T> bởi giá trị cho Init chức năng của bạn (và là một trong các nhà thầu), nhưng tất cả instantiations của UnaryFunction<> kết quả trong một lớp trừu tượng (mà không thể được truyền theo giá trị). Các giải pháp dễ dàng là sử dụng pass-by-reference cho UnaryFunction, để mapper đề cập đến đối tượng thực tế được truyền vào.

Giải pháp điển hình trong STL cho các functors là sử dụng một đối số mẫu riêng biệt, như sau:

template<typename T> 
template<typename Tin, Tmapper> 
void TemplateProblem<T>::Init(Tin * data, int length, Tmapper mapper, Tin bias) 
{ 
    T mappedBias = mapper(bias); 
    for (int i = 0; i < length; i++) 
    { 
     _data[i] = data[i] + mappedBias; 
    } 
} 

Sau đó, bạn không cần lớp cơ sở UnaryFunctionL<>. Nếu một không tương thích mapper được thông qua, điều này sẽ được chẩn đoán khi nó được sử dụng trong cơ thể của chức năng.

+0

Đối số mẫu 'Tmapper' đó hoạt động * và * giúp cuộc sống dễ dàng hơn. Cảm ơn rất nhiều! – primfaktor

Các vấn đề liên quan