简体   繁体   中英

C++ meta-programming with “invalid” template parameters - is it permitted?

In some of my code where I use meta-programming techniques, we use templated arguments that get forwarded elsewhere and later converted, so we never actually create instances of some of these classes.

In particular, we use std::vector<T> where T does not have the semantics to be included in a vector. In reality though we create a std::vector<shared_ptr<T> > .

The code looks a bit like this:

class Bar : noncopyable
{ 
    // whatever
};

class Foo : public FooInterface
{
  public:
    explicit Foo( std::vector< shared_ptr<Bar> > );
};

typedef Builder1Param< FooInterface, Foo, std::vector<Bar> > FooBuilder;

through clever meta-programming techniques, FooBuilder knows that it will pass in a vector<shared_ptr<Bar> > to Foo and not a vector<Bar> . The issue is that because Bar is non-copyable it is an invalid type for a vector.

Now the code compiles fine on any compiler that I have used this, but I would like to know if it is valid C++ (and will continue to be so into C++11 and beyond).

I should possibly add that Bar may actually be abstract (and often will be). The purpose is to indicate that the parameter is a collection of these (in a sense in the style of Java/C# references).

As long as you don't instantiate the type you're fine technically , same as with eg incomplete type.

However, it's a horrible design.

All that contortion in order make it possible to use more keypresses to write something misleading instead of just passing parameters.

I would reconsider that design.

Eg do

typedef Builder1Param< FooInterface, Foo, std::vector, Bar > FooBuilder;

For the template definition part, std::vector is here a template template parameter.

Using std::vector<Bar> in a program where Bar does not meet the requirements for std::vector produces undefined behaviour. This is from 17.6.4.8 [res.on.functions] in the C++11 Standard:

In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C ++ standard library depends on components supplied by a C ++ program. If these components do not meet their requirements, the Standard places no requirements on the implementation.

In particular, the effects are undefined in the following cases:

...

— for types used as template arguments when instantiating a template component, if the operations on the type do not implement the semantics of the applicable Requirements subclause (17.6.3.5, 23.2, 24.2, 26.2).

...

— if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM