2017-06-12 19 views
9
namespace N { 
    class C {}; 

    template<typename X> 
    char const * found(X && x) { 
     return "found"; 
    } 

    template<typename, typename X> 
    char const * notfound(X && x) { 
     return "not found"; 
    } 
} 

này định nghĩa một không gian tên N với một lớp C và hai mẫu chức năng. found có một tham số mẫu duy nhất, có thể được suy ra từ đối số hàm. notfound có tham số mẫu bổ sung không thể được suy ra.ADL không (hoặc không được thực hiện?) Cho chức năng với bổ sung (không suy luận) mẫu tham số

Với mã kiểm tra sau (on ideone):

#include <iostream> 
int main() { 
    N::C object; 
    std::cout 
     << found(object) << std::endl 
     << notfound<bool>(object) << std::endl // ERROR 
     << notfound<bool, N::C>(object) << std::endl; // ERROR 
} 

Tôi cho rằng argument dependent lookup sẽ tìm thấy cả hai foundnotfound qua không gian tên kèm theo trong cùng (đó là N) của các loại lập luận N::C.

Tuy nhiên:

prog.cpp: In function ‘int main()’: 
prog.cpp:21:6: error: ‘notfound’ was not declared in this scope 
    << notfound<bool>(object) << std::endl 
     ^~~~~~~~ 
prog.cpp:21:6: note: suggested alternative: 
prog.cpp:12:15: note: ‘N::notfound’ 
    char const * notfound(X && x) { 
       ^~~~~~~~ 

(cùng lỗi cho notfound<bool, N::C>(object) sau khi cho ý kiến ​​ra notfound<bool>(object) cuộc gọi)

Tại sao notfound không tìm thấy qua ADL?


Bối cảnh: Tôi đang thực hiện một chức năng get cho một số lớp wrapper, tất cả trong tất cả tương đối giống với std::get(std::tuple). Lớp bao bọc, là một chi tiết thực hiện, sống trong một số không gian tên lib::aspect::part::impl. Tôi không muốn người dùng của thư viện chỉ định using lib::aspect::part::impl::get vì lý do hiển nhiên.

Trả lời

8

Bởi vì một cuộc gọi hàm đến một mẫu chức năng với đối số mẫu được chỉ định rõ ràng yêu cầu tên của mẫu phải được tìm thấy bằng tra cứu thông thường; cho đến khi ADL mà không thể đá trong

Từ tiêu chuẩn:. $17.8.1/8 Explicit template argument specification [temp.arg.explicit]

(tôi nhấn mạnh)

[Lưu ý: Đối với tên hàm đơn giản, lập luận tra cứu phụ thuộc được áp dụng ngay cả khi tên hàm không hiển thị trong phạm vi cuộc gọi . Điều này là do cuộc gọi vẫn có dạng cú pháp của một cuộc gọi hàm ([basic.lookup.unqual]). Nhưng khi sử dụng mẫu chức năng với đối số mẫu rõ ràng, cuộc gọi không có mẫu cú pháp chính xác trừ khi có mẫu chức năng với tên hiển thị tại điểm gọi. Nếu không có tên như vậy hiển thị, cuộc gọi không được định dạng đúng cú pháp và tra cứu phụ thuộc vào đối số không áp dụng. Nếu một số tên như vậy được hiển thị, đối số phụ thuộc tra cứu sẽ áp dụng và các mẫu chức năng bổ sung có thể được tìm thấy trong các không gian tên khác.[Ví dụ:

namespace A { 
    struct B { }; 
    template<int X> void f(B); 
} 
namespace C { 
    template<class T> void f(T t); 
} 
void g(A::B b) { 
    f<3>(b);   // ill-formed: not a function call 
    A::f<3>(b);  // well-formed 
    C::f<3>(b);  // ill-formed; argument dependent lookup applies only to unqualified names 
    using C::f; 
    f<3>(b);   // well-formed because C​::​f is visible; then A​::​f is found by argument dependent lookup 
} 

- end dụ] - cuối note]

Câu cuối cùng đưa ra một cách giải quyết có thể; bạn có thể thêm tuyên bố của mẫu chức năng ở bất cứ đâu để làm cho tên hiển thị được gọi. ví dụ.

template<typename> 
void notfound(); 

int main() { 
    N::C object; 
    std::cout 
     << found(object) << std::endl 
     << notfound<bool>(object) << std::endl 
     << notfound<bool, N::C&>(object) << std::endl; // btw the 2nd template argument should be N::C& 
} 

LIVE

+0

Guess Lẽ ra tôi nên đọc toàn bộ trang ... Cảm ơn bạn;) –

+0

@DanielJour tôi argree rằng thật dễ dàng để bỏ qua. Và tôi thấy những giải thích từ tiêu chuẩn có vẻ rõ ràng hơn; Tôi đã sửa lại câu trả lời của mình và hy vọng nó có thể giúp ích nhiều hơn. – songyuanyao

+1

Một phần của lý do là vì '<' là mơ hồ; nó là một khung đối số mẫu hay nhỏ hơn? Giả sử nó là đối số 'std :: size_t'. 'notfound <7> (đối tượng)' là 'notfound <7' theo sau là'> (đối tượng) ' – Yakk

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