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.