2017-01-06 15 views
14

Giả sử tôi có một số lớp:Tôi có thể tạo mẫu chữ do người dùng xác định không?

template <typename T> 
class Foo { 
    const T* x_; 
public: 
    Foo(const T* str) : x_{str} {} 
}; 

và tôi cung cấp một số literals người dùng định nghĩa để tạo ra một đối tượng Foo:

Foo<char> operator"" _foo(const char* str, std::size_t) { 
    return Foo<char>{str}; 
} 

Foo<wchar_t> operator"" _foo(const wchar_t* str, std::size_t) { 
    return Foo<wchar_t>{str}; 
} 

// etc. for char16_t and char32_t. 

Câu hỏi của tôi là thế này: tại sao tôi không thể template này và tiết kiệm có viết lại mã?

template <typename T> 
Foo<T> operator"" _foo(const T* str, std::size_t) { 
    return Foo<T>{str}; 
} 

gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.4) và 7.0.0 (biên soạn bản thân mình) báo cáo:

nhắn
error: ‘Foo<T> operator""_foo(const T*, std::size_t)’ has invalid argument list 
Foo<T> operator"" _foo(const T* str, std::size_t) { 
               ^

Các lỗi có vẻ là đủ rõ ràng, nhưng Tôi không thấy lý do tại sao tôi không được phép làm điều này theo nguyên tắc; vì vậy, tôi đang làm điều này không chính xác, hoặc là điều này thực sự không được phép?

+0

2.14.8/3 gợi ý mẫu nhà điều hành do người dùng định nghĩa là hợp lệ. Per/5, mã của bạn dường như, với tôi, là chính xác. Trình biên dịch của bạn không chọn chuyên môn của toán tử mẫu (cụ thể) một toán tử _string_ literal do người dùng định nghĩa và mẫu fu của tôi không đủ tốt để tìm hiểu xem đây có phải là lỗi hay do các quy tắc tra cứu. –

+0

@LightnessRacesinOrbit Tôi đoán [over.literal] là phù hợp hơn ở đây. Dường như một mẫu chức năng liên quan đến id toán tử theo nghĩa đen phải tuân theo một khai báo cố định (nhiều hơn hoặc ít hơn 'mẫu« toán tử kép "" _x() '). Không có hình thức nào khác được cho phép. – skypjack

+1

@skypjack: Các từ ngữ làm cho tôi đề nghị thử nó với một instantiation rõ ràng. –

Trả lời

11

Cân nhắc this:

If the literal operator is a template, it must have an empty parameter list and can have only one template parameter, which must be a non-type template parameter pack with element type char

Nói cách khác, việc kê khai của một mẫu hành theo nghĩa đen nên là:

template <char...> double operator "" _x(); 

Đó không phải là trường hợp của bạn.


Tôi không phải là một ngôn ngữ-luật sư, nhưng tôi đoán phần của tiêu chuẩn có liên quan đối với trường hợp của bạn là [over.literal] (liên kết đến các dự thảo làm việc).

Một đoạn trích từ [over.literal]/2 sau:

A function template declared with a literal-operator-id is a literal operator template.

Dưới [over.literal]/5 được trích dẫn:

The declaration of a literal operator template shall have an empty parameter-declaration-clause and its template-parameter-list shall have a single template-parameter that is a non-type template parameter pack ([temp.variadic]) with element type char.

Dường như với tôi rằng tuyên bố tương tự như một trong câu hỏi là không được phép một cách rõ ràng bởi tiêu chuẩn.
Nói chung, một mẫu chức năng tuyên bố một toán tử theo nghĩa đen phải tuân theo đúng khuôn mẫu đã cho.


am I doing this incorrectly, or is this genuinely not allowed?

tôi sẽ nói đó là thực sự không được phép.

Dù sao, bạn vẫn có thể sử dụng một hàm template nếu bạn có logic phức tạp mà bạn không muốn lặp lại trong mỗi nhà khai thác:

template<typename T> 
Foo<T> create(const T *str) { 
    // your logic... 
    return Foo<T>{str}; 
} 

Foo<char> operator"" _foo(const char *str, std::size_t) { 
    return create(str); 
} 

Foo<wchar_t> operator"" _foo(const wchar_t *str, std::size_t) { 
    return create(str); 
} 

Đó là một vấn đề thêm một lớp về mình và đó là tất cả.
Rõ ràng, nó không có giá trị nếu tất cả các nhà điều hành của bạn là một chức năng cơ thể dòng.

+2

Tôi đoán đó là đủ rõ ràng. Tôi tự hỏi tại sao họ không cho phép điều này. Có lẽ các tiêu chuẩn trong tương lai sẽ thư giãn giải thưởng này ... – Zorawar

+1

@ Zorawar Tôi chỉ tò mò như bạn, nhưng tôi không thể hiểu tại sao nó không được phép. Tôi xin lôi. – skypjack

+1

OK! Cảm ơn câu trả lời. Ít nhất tôi biết tôi đã không mắc sai lầm ngu ngốc! – Zorawar

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