Tại sao không suy ra tham số mẫu từ hàm tạo?


102

câu hỏi của tôi hôm nay khá đơn giản: tại sao trình biên dịch không thể suy ra các tham số mẫu từ các hàm tạo lớp, nhiều như nó có thể làm từ các tham số hàm? Ví dụ: tại sao mã sau không thể hợp lệ:

template<typename obj>
class Variable {
      obj data;
      public: Variable(obj d)
              {
                   data = d;
              }
};

int main()
{
    int num = 2;
    Variable var(num); //would be equivalent to Variable<int> var(num),
    return 0;          //but actually a compile error
}

Như tôi đã nói, tôi hiểu rằng điều này không hợp lệ, vì vậy câu hỏi của tôi là tại sao lại không? Việc cho phép điều này có tạo ra bất kỳ lỗ hổng cú pháp chính nào không? Có trường hợp nào mà người ta không muốn có chức năng này (trong đó việc suy luận một kiểu sẽ gây ra vấn đề) không? Tôi chỉ đang cố gắng hiểu logic đằng sau việc cho phép suy luận mẫu cho các hàm, nhưng không phải cho các lớp được xây dựng phù hợp.


Tôi muốn mời một người nào đó (tôi một làm điều đó, chỉ cần không phải bây giờ), để biên dịch Drahakar và trả lời Pitis (ít nhất) là tốt phản ví dụ tại sao nó có thể không làm việc
jpinto3912

2
Cũng lưu ý rằng điều này có thể dễ dàng làm việc xung quanh quatemplate<class T> Variable<T> make_Variable(T&& p) {return Variable<T>(std::forward<T>(p));}
Mooing Duck

3
Bạn có thể nhận được những gì bạn muốn var = Variable <statementtype (n)> (n);
QuentinUK

18
C ++ 17 sẽ cho phép điều này! Đề xuất này đã được chấp nhận: open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0091r0.html
underscore_d

1
@underscore_d Tuyệt vời! Khoảng thời gian! Tôi cảm thấy tự nhiên đó là cách nó phải hoạt động, và nguồn gốc của sự kích ứng mà nó đã không.
amdn

Câu trả lời:


46

Tôi nghĩ rằng nó không hợp lệ vì hàm tạo không phải lúc nào cũng là điểm vào duy nhất của lớp (tôi đang nói về hàm tạo bản sao và toán tử =). Vì vậy, giả sử bạn đang sử dụng lớp của mình như thế này:

MyClass m(string s);
MyClass *pm;
*pm = m;

Tôi không chắc liệu trình phân tích cú pháp có rõ ràng như vậy không khi biết loại khuôn mẫu nào là pm MyClass;

Không chắc liệu những gì tôi nói có hợp lý không nhưng hãy bình luận thêm, đó là một câu hỏi thú vị.

C ++ 17

Người ta chấp nhận rằng C ++ 17 sẽ có kiểu trừ từ các đối số của hàm tạo.

Ví dụ:

std::pair p(2, 4.5);
std::tuple t(4, 3, 2.5);

Giấy được chấp nhận .


8
Đây thực sự là một điểm tuyệt vời mà tôi chưa bao giờ xem xét. Tôi không thấy bất kỳ cách nào xung quanh thực tế là con trỏ sẽ phải là kiểu cụ thể (tức là nó sẽ phải là MyClass <string> * pm). Nếu đúng như vậy, thì tất cả những gì bạn sẽ làm là cứu bản thân khỏi việc chỉ định loại khi khởi tạo; một vài ký tự đơn thuần của công việc phụ (và chỉ khi đối tượng được tạo trên ngăn xếp, không phải đống, như trên). Tôi luôn nghi ngờ rằng suy luận lớp có thể mở ra một khối sâu về cú pháp, và tôi nghĩ đây có thể là nó.
GRB

2
Tôi không hiểu rõ việc cho phép suy luận tham số mẫu từ các hàm tạo sẽ yêu cầu cho phép các khai báo không chuyên biệt mà không cần gọi hàm tạo như thế nào, như trong dòng thứ hai của bạn. Tức là, MyClass *pmở đây sẽ không hợp lệ vì lý do tương tự mà một hàm được khai báo template <typename T> void foo();không thể được gọi nếu không có chuyên môn hóa rõ ràng.
Kyle Strand

3
@KyleStrand Có, bằng cách nói rằng 'các đối số mẫu lớp không thể được suy ra từ các hàm tạo của chúng vì [ví dụ không sử dụng bất kỳ hàm tạo nào] ', câu trả lời này hoàn toàn không liên quan. Tôi thực sự không thể tin rằng nó đã được chấp nhận, đạt đến +29, mất 6 năm để một người nào đó nhận ra vấn đề chói sáng và ngồi không có một phiếu phản đối nào trong 7 năm. Không ai khác nghĩ trong khi họ đọc, hay ...?
underscore_d

1
@underscore_d Tôi thích cách, như hiện tại, câu trả lời này cho biết "có thể có một số vấn đề với đề xuất này; Tôi không chắc liệu những gì tôi vừa nói có hợp lý không (!), hãy bình luận (!!); và ồ nhân tiện đây là khá chính xác cách C ++ 17 sẽ hoạt động. "
Kyle Strand

1
@KyleStrand À vâng, đó là một vấn đề khác, mà tôi nhận thấy nhưng quên đề cập trong số tất cả những điều thú vị khác. Bản chỉnh sửa về C ++ 17 không phải do OP ... và IMO lẽ ra không được chấp thuận, nhưng được đăng dưới dạng một câu trả lời mới: nó sẽ được xác nhận là 'thay đổi ý nghĩa của bài đăng' ngay cả khi bài đăng có không có ý nghĩa gì khi bắt đầu ... Tôi không biết việc chỉnh sửa trong các phần hoàn toàn mới là trò chơi công bằng và chắc chắn đã có những chỉnh sửa ít gay gắt hơn bị từ chối, nhưng tôi đoán đó là may mắn của trận hòa nếu bạn nhận được người đánh giá.
underscore_d

27

Bạn không thể làm những gì bạn yêu cầu vì những lý do mà người khác đã giải quyết, nhưng bạn có thể làm điều này:

template<typename T>
class Variable {
    public: Variable(T d) {}
};
template<typename T>
Variable<T> make_variable(T instance) {
  return Variable<T>(instance);
}

cho tất cả mục đích và mục đích cũng giống như điều bạn yêu cầu. Nếu bạn thích đóng gói, bạn có thể làm cho make_variable một hàm thành viên tĩnh. Đó là cái mà người ta gọi là hàm tạo có tên. Vì vậy, nó không chỉ làm những gì bạn muốn mà còn gần như được gọi là những gì bạn muốn: trình biên dịch đang truyền tham số mẫu từ hàm tạo (được đặt tên).

NB: bất kỳ trình biên dịch hợp lý nào sẽ tối ưu hóa đối tượng tạm thời khi bạn viết một cái gì đó như

auto v = make_variable(instance);

6
Bạn muốn chỉ ra rằng việc tạo thành viên tĩnh của hàm trong trường hợp như vậy là không đặc biệt hữu ích vì đối với trường hợp đó bạn sẽ phải chỉ định đối số mẫu cho một lớp để gọi nó, vì vậy sẽ không có ích gì khi suy ra nó.
Predelnik

3
Và thậm chí tốt hơn trong C ++ 11 bạn có thể làm auto v = make_variable(instance)để bạn không thực sự phải xác định loại
Claudiu

1
Yeah, lol trước ý tưởng khai báo hàm make với tư cách là một staticthành viên ... hãy nghĩ về điều đó trong một giây tháng sáu. Điều đó sang một bên: các hàm tạo miễn phí thực sự giải pháp, nhưng nó có rất nhiều bảng soạn sẵn dư thừa, mà trong khi bạn đang gõ nó, bạn chỉ biết rằng bạn không cần phải làm vậy vì trình biên dịch có quyền truy cập vào tất cả thông tin bạn đang lặp lại. .. và may mắn thay C ++ 17 chứng minh điều đó.
underscore_d

21

Trong thời đại khai sáng năm 2016, với hai tiêu chuẩn mới của chúng tôi kể từ khi câu hỏi này được đặt ra và một tiêu chuẩn mới sắp xuất hiện, điều quan trọng cần biết là các trình biên dịch hỗ trợ tiêu chuẩn C ++ 17 sẽ biên dịch mã của bạn như hiện tại. .

Khấu trừ đối số mẫu cho các mẫu lớp trong C ++ 17

Đây (với sự chỉnh sửa của Olzhas Zhumabek về câu trả lời được chấp nhận) là bài báo trình bày chi tiết những thay đổi liên quan đối với tiêu chuẩn.

Giải quyết mối quan tâm từ các câu trả lời khác

Câu trả lời được xếp hạng hàng đầu hiện tại

Câu trả lời này chỉ ra rằng "phương thức tạo bản sao và operator=" sẽ không biết các chuyên ngành mẫu chính xác.

Điều này là vô nghĩa, bởi vì hàm tạo bản sao tiêu chuẩn và operator= chỉ tồn tại cho một loại mẫu đã biết :

template <typename T>
class MyClass {
    MyClass(const MyClass&) =default;
    ... etc...
};

// usage example modified from the answer
MyClass m(string("blah blah blah"));
MyClass *pm;   // WHAT IS THIS?
*pm = m;

Ở đây, như tôi đã lưu ý trong các ý kiến, có không có lý do để MyClass *pmtrở thành một tuyên bố pháp lý có hoặc không có các hình thức mới của suy luận: MyClass không phải là một loại (đó là một mẫu), do đó nó không có ý nghĩa để khai báo một con trỏ của loại MyClass. Đây là một cách có thể để sửa ví dụ:

MyClass m(string("blah blah blah"));
decltype(m) *pm;               // uses type inference!
*pm = m;

Dưới đây, pmđã về đúng loại, và do đó suy luận là tầm thường. Hơn nữa, không thể vô tình trộn các kiểu khi gọi hàm tạo bản sao:

MyClass m(string("blah blah blah"));
auto pm = &(MyClass(m));

Đây, pmsẽ là một con trỏ đến một bản sao của m. Ở đây, MyClassđang được sao chép xây dựng từ m— loại nào MyClass<string>(và không thuộc loại không tồn tại MyClass). Do đó, tại điểm mà pm's loại được suy ra, có đủ thông tin để biết rằng mẫu-loại m, và do đó mẫu-loại pm, là string.

Hơn nữa, phần sau sẽ luôn phát sinh lỗi biên dịch :

MyClass s(string("blah blah blah"));
MyClass i(3);
i = s;

Điều này là do khai báo của hàm tạo bản sao không được tạo mẫu:

MyClass(const MyClass&);

Ở đây, kiểu mẫu của đối số copy-constructor khớp với kiểu mẫu của lớp nói chung; tức là, khi nào MyClass<string>được khởi tạo, MyClass<string>::MyClass(const MyClass<string>&);được khởi tạo cùng với nó, và khi nào MyClass<int>được khởi tạo, MyClass<int>::MyClass(const MyClass<int>&);được khởi tạo. Trừ khi nó được chỉ định rõ ràng hoặc một phương thức khởi tạo được tạo mẫu được khai báo, không có lý do gì để trình biên dịch khởi tạo MyClass<int>::MyClass(const MyClass<string>&);, điều này rõ ràng là không phù hợp.

Câu trả lời của Cătălin Pitiș

Pitiș đưa ra một ví dụ về suy luận Variable<int>Variable<double>sau đó nói:

Tôi có cùng một tên loại (Biến) trong mã cho hai loại khác nhau (Biến và Biến). Theo quan điểm chủ quan của tôi, nó ảnh hưởng khá nhiều đến khả năng đọc của mã.

Như đã lưu ý trong ví dụ trước, Variablebản thân nó không phải là một tên kiểu, mặc dù tính năng mới làm cho nó giống như một cú pháp.

Pitiș sau đó hỏi điều gì sẽ xảy ra nếu không có hàm tạo nào được đưa ra để cho phép suy luận thích hợp. Câu trả lời là không cho phép suy luận, bởi vì suy luận được kích hoạt bởi lời gọi hàm tạo . Không có lời gọi hàm tạo, không có suy luận .

Điều này tương tự như hỏi phiên bản nào foođược suy ra ở đây:

template <typename T> foo();
foo();

Câu trả lời là mã này là bất hợp pháp, vì lý do đã nêu.

Câu trả lời của MSalter

Theo như tôi có thể nói thì đây là câu trả lời duy nhất để đưa ra mối quan tâm chính đáng về tính năng được đề xuất.

Ví dụ là:

Variable var(num);  // If equivalent to Variable<int> var(num),
Variable var2(var); // Variable<int> or Variable<Variable<int>> ?

Câu hỏi quan trọng là, trình biên dịch chọn hàm tạo suy ra kiểu ở đây hay hàm tạo sao chép ?

Thử mã ra, chúng ta có thể thấy rằng hàm tạo bản sao đã được chọn. Để mở rộng ví dụ :

Variable var(num);          // infering ctor
Variable var2(var);         // copy ctor
Variable var3(move(var));   // move ctor
// Variable var4(Variable(num));     // compiler error

Tôi không chắc đề xuất và phiên bản mới của tiêu chuẩn quy định điều này như thế nào; nó dường như được xác định bởi "hướng dẫn khấu trừ", là một chút tiêu chuẩn mới mà tôi chưa hiểu.

Tôi cũng không chắc tại sao var4khoản khấu trừ là bất hợp pháp; lỗi trình biên dịch từ g ++ dường như chỉ ra rằng câu lệnh đang được phân tích cú pháp như một khai báo hàm.


Thật là một câu trả lời tuyệt vời, chi tiết! var4chỉ là một trường hợp "phân tích cú pháp gây khó chịu nhất" (không liên quan đến suy luận khuôn mẫu). Chúng tôi đã từng chỉ sử dụng thêm parens cho việc này, nhưng ngày nay tôi nghĩ rằng sử dụng niềng răng để biểu thị rõ ràng việc xây dựng là lời khuyên thông thường.
Sumudu Fernando

@SumuduFernando Cảm ơn! Ý bạn là nó Variable var4(Variable(num));được coi như một khai báo hàm? Nếu vậy, tại sao lại là Variable(num)một đặc tả tham số hợp lệ?
Kyle Strand

@SumuduFernando Đừng bận tâm, tôi không biết điều này là hợp lệ: coliru.stacked-crooked.com/a/98c36b8082660941
Kyle Strand,

11

Vẫn còn thiếu: Nó làm cho mã sau khá mơ hồ:

int main()
{
    int num = 2;
    Variable var(num);  // If equivalent to Variable<int> var(num),
    Variable var2(var); //Variable<int> or Variable<Variable<int>> ?
}

Một điểm tốt nữa. Giả sử rằng tồn tại một biến được xác định bởi phương thức tạo bản sao (Variable <obj> d), thì sẽ phải có một số loại ưu tiên được thiết lập.
GRB

1
Hoặc, cách khác, yêu cầu trình biên dịch ném lại lỗi tham số mẫu không xác định, giống như tôi đã đề xuất liên quan đến câu trả lời của Pitis. Tuy nhiên, nếu bạn đi theo con đường đó, số lần suy luận có thể xảy ra mà không có vấn đề (lỗi) ngày càng ít đi.
GRB

Đây thực sự là một điểm thú vị và (như tôi đã lưu ý trong câu trả lời của mình) Tôi vẫn chưa chắc chắn cách đề xuất C ++ 17 được chấp nhận giải quyết vấn đề này.
Kyle Strand

9

Giả sử rằng trình biên dịch hỗ trợ những gì bạn yêu cầu. Sau đó, mã này hợp lệ:

Variable v1( 10); // Variable<int>

// Some code here

Variable v2( 20.4); // Variable<double>

Bây giờ, tôi có cùng một tên loại (Biến) trong mã cho hai loại khác nhau (Biến và Biến). Theo quan điểm chủ quan của tôi, nó ảnh hưởng khá nhiều đến khả năng đọc của mã. Có cùng một tên kiểu cho hai kiểu khác nhau trong cùng một không gian tên sẽ gây hiểu lầm cho tôi.

Cập nhật sau: Một điều khác cần xem xét: chuyên môn hóa một phần (hoặc toàn bộ) mẫu.

Điều gì sẽ xảy ra nếu tôi chuyên biệt hóa Biến và không cung cấp hàm tạo như bạn mong đợi?

Vì vậy, tôi sẽ có:

template<>
class Variable<int>
{
// Provide default constructor only.
};

Sau đó, tôi có mã:

Variable v( 10);

Trình biên dịch phải làm gì? Sử dụng định nghĩa lớp Biến chung chung để suy ra rằng đó là Biến, sau đó khám phá rằng Biến không cung cấp một hàm tạo tham số?


1
Tệ hơn nữa: điều gì sẽ xảy ra nếu bạn chỉ có Variable <int> :: Variable (float)? Bây giờ bạn có hai cách để suy ra Biến (1f) và không có cách nào để suy ra Biến (1).
MSalters

Đó là một điểm tốt, nhưng có thể được dễ dàng vượt qua bằng phương pháp đúc: v1 Variable ((double) 10)
jpinto3912

Tôi đồng ý rằng khả năng đọc mã là một vấn đề chủ quan, tuy nhiên, tôi đồng ý 100% với những gì bạn đang nói về chuyên môn hóa mẫu. Giải pháp có thể là đưa ra lỗi tham số mẫu không xác định (một khi trình biên dịch xem xét chuyên môn <int> và không thấy các hàm tạo hợp lệ, có nghĩa là nó không biết bạn muốn sử dụng mẫu nào và bạn phải chỉ định rõ ràng) nhưng Tôi đồng ý rằng nó không phải là một giải pháp tốt. Tôi sẽ thêm điều này như một lỗ hổng cú pháp chính khác cần được xử lý (nhưng có thể được giải quyết nếu người ta chấp nhận hậu quả).
GRB

4
@ jpinto3912 - bạn đang thiếu điểm. Trình biên dịch phải khởi tạo TẤT CẢ các biến <T> có thể có để kiểm tra xem BẤT KỲ Biến ctor nào <T> :: Biến cung cấp một ctor không rõ ràng hay không. Thoát khỏi sự mơ hồ không phải là vấn đề - đơn giản hãy tự khởi tạo Biến <đôi> nếu đó là điều bạn muốn. Nó phát hiện ra sự mơ hồ ngay từ đầu khiến nó không thể.
MSalters

6

C ++ 03 và C ++ 11 tiêu chuẩn không cho phép khấu trừ đối số mẫu từ các tham số được truyền cho hằng số.

Nhưng có một đề xuất cho "Suy ra tham số mẫu cho các hàm tạo" để bạn có thể sớm nhận được những gì bạn yêu cầu. Chỉnh sửa: thực sự, tính năng này đã được xác nhận cho C ++ 17.

Xem: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3602.htmlhttp://www.open-std.org/jtc1/sc22/wg21/docs/ paper / 2015 / p0091r0.html


Tính năng này đã được thêm vào C ++ 17, nhưng không phải nếu "sớm" áp dụng cho khung thời gian từ 6 đến 8 năm. ;)
ChetS

2

Rất nhiều lớp không phụ thuộc vào các tham số của hàm tạo. Chỉ có một số lớp chỉ có một hàm tạo và tham số hóa dựa trên (các) kiểu của hàm tạo này.

Nếu bạn thực sự cần suy luận mẫu, hãy sử dụng hàm trợ giúp:

template<typename obj>
class Variable 
{
      obj data;
public: 
      Variable(obj d)
      : data(d)
      { }
};

template<typename obj>
inline Variable<obj> makeVariable(const obj& d)
{
    return Variable<obj>(d);
}

1
Tất nhiên chức năng này chỉ tỏ ra hữu ích đối với một số lớp, nhưng điều tương tự cũng có thể nói đối với suy luận hàm. Không phải tất cả các hàm được tạo mẫu đều lấy tham số của chúng từ danh sách đối số, nhưng chúng tôi cho phép suy luận cho những hàm đó.
GRB

1

Khấu trừ kiểu bị giới hạn trong các hàm mẫu trong C ++ hiện tại, nhưng từ lâu người ta đã nhận ra rằng việc khấu trừ kiểu trong các ngữ cảnh khác sẽ rất hữu ích. Do đó C ++ 0x's auto.

Mặc dù chính xác những gì bạn đề xuất sẽ không thể thực hiện được trong C ++ 0x, nhưng những điều sau đây cho thấy bạn có thể đến khá gần:

template <class X>
Variable<typename std::remove_reference<X>::type> MakeVariable(X&& x)
{
    // remove reference required for the case that x is an lvalue
    return Variable<typename std::remove_reference<X>::type>(std::forward(x));
}

void test()
{
    auto v = MakeVariable(2); // v is of type Variable<int>
}

0

Bạn nói đúng, trình biên dịch có thể dễ dàng đoán được, nhưng nó không nằm trong tiêu chuẩn hoặc C ++ 0x theo như tôi biết, vì vậy bạn sẽ phải đợi ít nhất 10 năm nữa (tỷ lệ quay vòng cố định tiêu chuẩn ISO) trước khi các nhà cung cấp trình biên dịch thêm tính năng này


Điều đó không đúng với tiêu chuẩn sắp tới, một từ khóa tự động sẽ được giới thiệu. Hãy xem bài đăng của James Hopkins trong chủ đề này. stackoverflow.com/questions/984394/… . Anh ấy chỉ ra cách nó sẽ khả thi trong C ++ 0x.
buồng trứng

1
Chỉ để sửa lại bản thân tôi, từ khóa tự động cũng có trong tiêu chuẩn hiện tại, nhưng cho mục đích khác.
buồng trứng

Có vẻ như sẽ là 8 năm (kể từ thời điểm có câu trả lời này) ... vì vậy 10 năm không phải là một dự đoán tồi, mặc dù đã có hai tiêu chuẩn trong thời gian ngắn!
Kyle Strand

-1

Hãy xem xét vấn đề với tham chiếu đến một lớp mà mọi người nên quen thuộc với - std :: vector.

Đầu tiên, một cách sử dụng vector rất phổ biến là sử dụng hàm tạo không nhận tham số:

vector <int> v;

Trong trường hợp này, rõ ràng là không thể suy luận được.

Cách sử dụng phổ biến thứ hai là tạo một vectơ có kích thước trước:

vector <string> v(100);

Ở đây, nếu suy luận được sử dụng:

vector v(100);

chúng ta nhận được một vectơ gồm int, không phải chuỗi, và có lẽ nó không có kích thước!

Cuối cùng, hãy xem xét các hàm tạo nhận nhiều tham số - với "suy luận":

vector v( 100, foobar() );      // foobar is some class

Tham số nào nên được sử dụng để suy luận? Chúng tôi sẽ cần một số cách để nói với trình biên dịch rằng nó phải là trình biên dịch thứ hai.

Với tất cả những vấn đề này cho một lớp đơn giản như vector, thật dễ dàng để hiểu tại sao suy luận không được sử dụng.


3
Tôi nghĩ rằng bạn đang hiểu sai ý tưởng. Suy luận kiểu cho các hàm tạo sẽ chỉ xảy ra NẾU kiểu mẫu là một phần của hàm tạo. Giả sử rằng vectơ có mẫu định nghĩa mẫu <typename T>. Ví dụ của bạn không phải là vấn đề vì hàm tạo của vectơ sẽ được định nghĩa là vectơ (kích thước int), không phải vectơ (kích thước T). Chỉ trong trường hợp vectơ (kích thước T) mới xảy ra bất kỳ suy luận nào; trong ví dụ đầu tiên, trình biên dịch sẽ đưa ra lỗi nói rằng T là không xác định. Về cơ bản giống với cách hoạt động của suy luận mẫu hàm.
GRB

Vì vậy, nó sẽ chỉ diễn ra đối với các hàm tạo có một tham số duy nhất và tham số đó là kiểu tham số mẫu? Đó dường như là một số lượng nhỏ các trường hợp biến mất.

Nó không nhất thiết phải là một tham số duy nhất. Ví dụ, một người có thể có một phương thức khởi tạo vector của vector (int size, T firstElement). Nếu một mẫu có nhiều tham số (mẫu <typename T, typename U>), một mẫu có thể có Holder :: Holder (T firstObject, U secondObject). Nếu một mẫu có nhiều tham số nhưng hàm tạo chỉ lấy một trong số chúng, ví dụ: Holder (U secondObject), thì T sẽ luôn phải được phát biểu rõ ràng. Các quy tắc sẽ tương tự như suy luận mẫu hàm càng tốt.
GRB

-2

Đặt ctor làm mẫu, Biến có thể chỉ có một biểu mẫu nhưng có nhiều ctor khác nhau:

class Variable {
      obj data; // let the compiler guess
      public:
      template<typename obj>
      Variable(obj d)
       {
           data = d;
       }
};

int main()
{
    int num = 2;
    Variable var(num);  // Variable::data int?

    float num2 = 2.0f;
    Variable var2(num2);  // Variable::data float?
    return 0;         
}

Xem? Chúng ta không thể có nhiều thành viên dữ liệu Variable ::.


Điều đó sẽ không có ý nghĩa trong bất kỳ kịch bản nào. obj về mặt dữ liệu obj là không xác định vì lớp đó không còn là một khuôn mẫu. Mã như vậy sẽ không hợp lệ theo cả hai cách.
GRB

Tôi muốn hành vi của trình biên dịch mà bạn mô tả, vì vậy tôi tìm ra cách để bỏ qua hạn chế đó (trong trường hợp của tôi), mà bạn có thể thấy thú vị, stackoverflow.com/questions/228620/garbage-collection-in-c-why/…
Nick Dandoulakis

-2

Xem Phần khấu trừ đối số của mẫu C ++ để biết thêm thông tin về điều này.


4
Tôi đã đọc bài báo này trước đây và nó dường như không nói nhiều về những gì tôi đang nói. Lần duy nhất người viết có vẻ nói về suy luận đối số liên quan đến các lớp học là khi anh ta nói rằng điều đó không thể được thực hiện ở đầu bài báo;) - nếu bạn có thể chỉ ra những phần mà bạn nghĩ là có liên quan mặc dù tôi ' d thực sự đánh giá cao điều đó.
GRB
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.